i18ntk 2.0.4 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +38 -60
  2. package/main/i18ntk-analyze.js +49 -44
  3. package/main/i18ntk-complete.js +75 -74
  4. package/main/i18ntk-fixer.js +3 -3
  5. package/main/i18ntk-init.js +5 -5
  6. package/main/i18ntk-scanner.js +2 -2
  7. package/main/i18ntk-sizing.js +35 -35
  8. package/main/i18ntk-summary.js +4 -4
  9. package/main/i18ntk-ui.js +54 -8
  10. package/main/i18ntk-usage.js +14 -14
  11. package/main/i18ntk-validate.js +6 -5
  12. package/main/manage/commands/AnalyzeCommand.js +40 -35
  13. package/main/manage/commands/FixerCommand.js +2 -2
  14. package/main/manage/commands/ScannerCommand.js +2 -2
  15. package/main/manage/commands/ValidateCommand.js +9 -9
  16. package/main/manage/index.js +147 -75
  17. package/main/manage/managers/LanguageMenu.js +7 -2
  18. package/main/manage/services/UsageService.js +7 -7
  19. package/package.json +269 -290
  20. package/settings/settings-cli.js +3 -3
  21. package/ui-locales/de.json +161 -166
  22. package/ui-locales/en.json +13 -18
  23. package/ui-locales/es.json +171 -184
  24. package/ui-locales/fr.json +155 -161
  25. package/ui-locales/ja.json +192 -243
  26. package/ui-locales/ru.json +145 -196
  27. package/ui-locales/zh.json +179 -185
  28. package/utils/cli-helper.js +26 -98
  29. package/utils/extractors/regex.js +39 -12
  30. package/utils/i18n-helper.js +88 -40
  31. package/{scripts → utils}/locale-optimizer.js +61 -60
  32. package/utils/security-check-improved.js +16 -13
  33. package/utils/security.js +6 -4
  34. package/main/i18ntk-go.js +0 -283
  35. package/main/i18ntk-java.js +0 -380
  36. package/main/i18ntk-js.js +0 -512
  37. package/main/i18ntk-manage.js +0 -1694
  38. package/main/i18ntk-php.js +0 -462
  39. package/main/i18ntk-py.js +0 -379
  40. package/main/i18ntk-settings.js +0 -23
  41. package/main/manage/index-fixed.js +0 -1447
  42. package/main/manage/services/ConfigurationService-fixed.js +0 -449
  43. package/scripts/build-lite.js +0 -279
  44. package/scripts/deprecate-versions.js +0 -317
  45. package/scripts/export-translations.js +0 -84
  46. package/scripts/fix-all-i18n.js +0 -215
  47. package/scripts/fix-and-purify-i18n.js +0 -213
  48. package/scripts/fix-locale-control-chars.js +0 -110
  49. package/scripts/lint-locales.js +0 -80
  50. package/scripts/prepublish.js +0 -348
  51. package/scripts/security-check.js +0 -117
  52. package/scripts/sync-translations.js +0 -151
  53. package/scripts/sync-ui-locales.js +0 -20
  54. package/scripts/validate-all-translations.js +0 -139
  55. package/scripts/verify-deprecations.js +0 -157
  56. package/scripts/verify-translations.js +0 -63
  57. package/utils/security-fixed.js +0 -607
@@ -1,279 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Lightweight Build Script for Lite Distribution
4
- *
5
- * Creates an optimized package containing only essential files
6
- * and the English UI locale to reduce bundle size.
7
- *
8
- * @version 1.10.0
9
- * @since 2025-08-08
10
- */
11
-
12
- const fs = require('fs');
13
- const path = require('path');
14
-
15
- class LiteBuild {
16
- constructor() {
17
- this.projectRoot = path.resolve(__dirname, '..');
18
- this.buildDir = path.join(this.projectRoot, 'dist-lite');
19
- this.packageJson = require('../package.json');
20
- }
21
-
22
- async build() {
23
- console.log('šŸš€ Starting lite build process...');
24
-
25
- try {
26
- // Clean previous build
27
- await this.cleanBuildDir();
28
-
29
- // Create build directory structure
30
- await this.createBuildStructure();
31
-
32
- // Copy essential files
33
- await this.copyEssentialFiles();
34
-
35
- // Copy only English locale
36
- await this.copyEnglishLocale();
37
-
38
- // Create optimized package.json
39
- await this.createOptimizedPackageJson();
40
-
41
- // Create .npmignore for lite package
42
- await this.createNpmIgnore();
43
-
44
- // Generate build report
45
- await this.generateBuildReport();
46
-
47
- console.log('āœ… Lite build completed successfully!');
48
- console.log(`šŸ“¦ Build directory: ${this.buildDir}`);
49
-
50
- } catch (error) {
51
- console.error('āŒ Build failed:', error.message);
52
- process.exit(1);
53
- }
54
- }
55
-
56
- async cleanBuildDir() {
57
- if (SecurityUtils.safeExistsSync(this.buildDir)) {
58
- fs.rmSync(this.buildDir, { recursive: true, force: true });
59
- }
60
- fs.mkdirSync(this.buildDir, { recursive: true });
61
- }
62
-
63
- async createBuildStructure() {
64
- const dirs = [
65
- 'main',
66
- 'utils',
67
- 'settings',
68
- 'resources/i18n/ui-locales/en',
69
- 'scripts'
70
- ];
71
-
72
- dirs.forEach(dir => {
73
- fs.mkdirSync(path.join(this.buildDir, dir), { recursive: true });
74
- });
75
- }
76
-
77
- async copyEssentialFiles() {
78
- const essentialFiles = [
79
- // Main CLI scripts
80
- { src: 'main/manage/index.js', dest: 'main/manage/index.js' },
81
- { src: 'main/i18ntk-init.js', dest: 'main/i18ntk-init.js' },
82
- { src: 'main/i18ntk-analyze.js', dest: 'main/i18ntk-analyze.js' },
83
- { src: 'main/i18ntk-validate.js', dest: 'main/i18ntk-validate.js' },
84
- { src: 'main/i18ntk-ui.js', dest: 'main/i18ntk-ui.js' },
85
-
86
- // Utilities
87
- { src: 'utils/security.js', dest: 'utils/security.js' },
88
- { src: 'utils/i18n-helper.js', dest: 'utils/i18n-helper.js' },
89
- { src: 'utils/admin-auth.js', dest: 'utils/admin-auth.js' },
90
- { src: 'utils/cli-helper.js', dest: 'utils/cli-helper.js' },
91
-
92
- // Settings
93
- { src: 'settings/i18ntk-config.json', dest: 'settings/i18ntk-config.json' },
94
- { src: 'settings/settings-manager.js', dest: 'settings/settings-manager.js' },
95
- { src: 'settings/settings-cli.js', dest: 'settings/settings-cli.js' },
96
-
97
- // Scripts
98
- { src: 'scripts/build-lite.js', dest: 'scripts/build-lite.js' },
99
-
100
- // Root files
101
- { src: 'README.md', dest: 'README.md' },
102
- { src: 'LICENSE', dest: 'LICENSE' }
103
- ];
104
-
105
- essentialFiles.forEach(({ src, dest }) => {
106
- const srcPath = path.join(this.projectRoot, src);
107
- const destPath = path.join(this.buildDir, dest);
108
-
109
- if (SecurityUtils.safeExistsSync(srcPath)) {
110
- fs.copyFileSync(srcPath, destPath);
111
- }
112
- });
113
- }
114
-
115
- async copyEnglishLocale() {
116
- const enLocaleDir = path.join(this.projectRoot, 'resources', 'i18n', 'ui-locales', 'en');
117
- const destDir = path.join(this.buildDir, 'resources', 'i18n', 'ui-locales', 'en');
118
-
119
- if (SecurityUtils.safeExistsSync(enLocaleDir)) {
120
- const files = fs.readdirSync(enLocaleDir);
121
- files.forEach(file => {
122
- if (file.endsWith('.json')) {
123
- fs.copyFileSync(
124
- path.join(enLocaleDir, file),
125
- path.join(destDir, file)
126
- );
127
- }
128
- });
129
- }
130
- }
131
-
132
- async createOptimizedPackageJson() {
133
- const litePackageJson = {
134
- name: this.packageJson.name + '-lite',
135
- version: this.packageJson.version,
136
- description: 'Lite version of i18n Management Toolkit with English UI only',
137
- main: this.packageJson.main,
138
- bin: this.packageJson.bin,
139
- scripts: {
140
- start: 'node main/manage/index.js',
141
- analyze: 'node main/i18ntk-analyze.js',
142
- validate: 'node main/i18ntk-validate.js'
143
- },
144
- keywords: this.packageJson.keywords,
145
- author: this.packageJson.author,
146
- license: this.packageJson.license,
147
- engines: this.packageJson.engines,
148
- repository: this.packageJson.repository,
149
- bugs: this.packageJson.bugs,
150
- homepage: this.packageJson.homepage
151
- };
152
-
153
- SecurityUtils.safeWriteFileSync(
154
- path.join(this.buildDir, 'package.json'),
155
- JSON.stringify(litePackageJson, null, 2)
156
- );
157
- }
158
-
159
- async createNpmIgnore() {
160
- const npmIgnoreContent = `
161
- # Development files
162
- dev/
163
- tests/
164
- benchmarks/
165
- docs/
166
- .github/
167
- .i18ntk/
168
-
169
- # Non-English locales
170
- resources/i18n/ui-locales/es/
171
- resources/i18n/ui-locales/fr/
172
- resources/i18n/ui-locales/de/
173
- resources/i18n/ui-locales/ja/
174
- resources/i18n/ui-locales/ru/
175
- resources/i18n/ui-locales/zh/
176
-
177
- # Debug and test files
178
- *.test.js
179
- *.spec.js
180
- debug-*.js
181
- test-*.html
182
-
183
- # Build artifacts
184
- node_modules/
185
- dist/
186
- *.log
187
- .DS_Store
188
- *.tmp
189
- *.temp
190
-
191
- # Source control
192
- .git/
193
- .gitignore
194
- .gitattributes
195
-
196
- # IDE files
197
- .vscode/
198
- .idea/
199
- *.swp
200
- *.swo
201
- *~
202
-
203
- # OS files
204
- Thumbs.db
205
- .DS_Store
206
- `;
207
-
208
- SecurityUtils.safeWriteFileSync(
209
- path.join(this.buildDir, '.npmignore'),
210
- npmIgnoreContent.trim()
211
- );
212
- }
213
-
214
- async generateBuildReport() {
215
- const stats = this.getBuildStats();
216
- const report = {
217
- version: this.packageJson.version,
218
- buildDate: new Date().toISOString(),
219
- totalFiles: stats.totalFiles,
220
- totalSize: stats.totalSize,
221
- languages: ['en'],
222
- optimization: {
223
- sizeReduction: stats.sizeReduction,
224
- fileReduction: stats.fileReduction
225
- }
226
- };
227
-
228
- SecurityUtils.safeWriteFileSync(
229
- path.join(this.buildDir, 'build-report.json'),
230
- JSON.stringify(report, null, 2)
231
- );
232
-
233
- console.log('\nšŸ“Š Build Statistics:');
234
- console.log(` Files: ${stats.totalFiles}`);
235
- console.log(` Size: ${(stats.totalSize / 1024).toFixed(2)} KB`);
236
- console.log(` Languages: English only`);
237
- console.log(` Size reduction: ${stats.sizeReduction}%`);
238
- }
239
-
240
- getBuildStats() {
241
- let totalFiles = 0;
242
- let totalSize = 0;
243
-
244
- const countFiles = (dir) => {
245
- const files = fs.readdirSync(dir);
246
- files.forEach(file => {
247
- const filePath = path.join(dir, file);
248
- const stat = fs.statSync(filePath);
249
-
250
- if (stat.isDirectory()) {
251
- countFiles(filePath);
252
- } else {
253
- totalFiles++;
254
- totalSize += stat.size;
255
- }
256
- });
257
- };
258
-
259
- countFiles(this.buildDir);
260
-
261
- // Calculate size reduction (rough estimate)
262
- const originalSize = 2500 * 1024; // ~2.5MB original
263
- const sizeReduction = Math.round(((originalSize - totalSize) / originalSize) * 100);
264
-
265
- return {
266
- totalFiles,
267
- totalSize,
268
- sizeReduction
269
- };
270
- }
271
- }
272
-
273
- // Run if called directly
274
- if (require.main === module) {
275
- const builder = new LiteBuild();
276
- builder.build();
277
- }
278
-
279
- module.exports = LiteBuild;
@@ -1,317 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * i18ntk Intelligent Version Deprecation Script
5
- *
6
- * This script intelligently manages version deprecations for i18ntk.
7
- * Features:
8
- * - Checks existing deprecation status to avoid re-deprecating
9
- * - Admin configuration support via deprecation-config.json
10
- * - Selective deprecation based on version patterns
11
- * - Comprehensive reporting and error handling
12
- */
13
-
14
- const { execSync } = require('child_process');
15
- const path = require('path');
16
- const SecurityUtils = require('../utils/security');
17
-
18
- // Configuration
19
- const CONFIG_FILE = path.join(__dirname, '..', 'deprecation-config.json');
20
- const packageJsonPath = path.join(__dirname, '..', 'package.json');
21
-
22
- // Securely read package.json
23
- const packageJsonContent = SecurityUtils.safeReadFileSync(packageJsonPath, path.dirname(packageJsonPath), 'utf8');
24
- if (!packageJsonContent) {
25
- console.error('āŒ Failed to read package.json');
26
- process.exit(1);
27
- }
28
-
29
- const packageJson = SecurityUtils.safeParseJSON(packageJsonContent);
30
- if (!packageJson) {
31
- console.error('āŒ Failed to parse package.json');
32
- process.exit(1);
33
- }
34
-
35
- const deprecationMessage = 'āš ļø DEPRECATED: This version contains security vulnerabilities and missing features. Please upgrade to i18ntk@1.10.0 for: šŸ”’ Zero shell access security, šŸš€ 97% performance improvement, šŸ Python framework support, and šŸ›”ļø PIN protection. Run: npm install i18ntk@latest';
36
-
37
- // Default deprecation list from package.json
38
- const defaultVersionsToDeprecate = packageJson.versionInfo.deprecations;
39
-
40
- // Load admin configuration if available
41
- function loadAdminConfig() {
42
- if (SecurityUtils.safeExistsSync(CONFIG_FILE, path.dirname(CONFIG_FILE))) {
43
- try {
44
- const configContent = SecurityUtils.safeReadFileSync(CONFIG_FILE, path.dirname(CONFIG_FILE), 'utf8');
45
- if (configContent) {
46
- const config = SecurityUtils.safeParseJSON(configContent);
47
- if (config) {
48
- console.log('šŸ“‹ Using admin configuration from deprecation-config.json');
49
- return config;
50
- }
51
- }
52
- } catch (error) {
53
- console.warn('āš ļø Could not read admin config, using defaults:', error.message);
54
- }
55
- }
56
- return null;
57
- }
58
-
59
- // Get versions to deprecate from config or defaults
60
- function getVersionsToDeprecate() {
61
- const adminConfig = loadAdminConfig();
62
- if (adminConfig && adminConfig.versionsToDeprecate) {
63
- return adminConfig.versionsToDeprecate;
64
- }
65
- return defaultVersionsToDeprecate;
66
- }
67
-
68
- // Check if a version is already deprecated
69
- function isVersionDeprecated(version) {
70
- try {
71
- const output = execSync(`npm view i18ntk@${version} --json`, { encoding: 'utf8' });
72
- const versionInfo = JSON.parse(output);
73
- return versionInfo.deprecated !== undefined;
74
- } catch (error) {
75
- // If we can't check, assume it's not deprecated to be safe
76
- return false;
77
- }
78
- }
79
-
80
- // Get all published versions
81
- function getPublishedVersions() {
82
- try {
83
- const output = execSync('npm view i18ntk versions --json', { encoding: 'utf8' });
84
- return JSON.parse(output);
85
- } catch (error) {
86
- console.error('āŒ Failed to get published versions:', error.message);
87
- process.exit(1);
88
- }
89
- }
90
-
91
- // Get deprecation status for all versions
92
- function getDeprecationStatus() {
93
- const publishedVersions = getPublishedVersions();
94
- const currentVersion = packageJson.version;
95
- const status = {
96
- published: publishedVersions,
97
- current: currentVersion,
98
- alreadyDeprecated: [],
99
- notDeprecated: [],
100
- errors: []
101
- };
102
-
103
- console.log(`šŸ“Š Checking deprecation status for ${publishedVersions.length} versions...`);
104
-
105
- for (const version of publishedVersions) {
106
- if (version === currentVersion) {
107
- continue; // Skip current version
108
- }
109
-
110
- try {
111
- if (isVersionDeprecated(version)) {
112
- status.alreadyDeprecated.push(version);
113
- } else {
114
- status.notDeprecated.push(version);
115
- }
116
- } catch (error) {
117
- status.errors.push({ version, error: error.message });
118
- }
119
-
120
- // Small delay to avoid overwhelming npm registry
121
- // await new Promise(resolve => setTimeout(resolve, 100));
122
- }
123
-
124
- return status;
125
- }
126
-
127
- // Deprecate a single version
128
- function deprecateVersion(version, message) {
129
- try {
130
- console.log(`šŸ”„ Deprecating ${version}...`);
131
- execSync(`npm deprecate i18ntk@${version} "${message}"`, { stdio: 'inherit' });
132
- console.log(`āœ… Successfully deprecated ${version}`);
133
- return true;
134
- } catch (error) {
135
- console.error(`āŒ Failed to deprecate ${version}:`, error.message);
136
- return false;
137
- }
138
- }
139
-
140
- // Expand version ranges (e.g., "1.0.x" -> ["1.0.0", "1.0.1", "1.0.2", ...])
141
- function expandVersionRange(versionRange) {
142
- if (!versionRange.includes('x')) {
143
- return [versionRange];
144
- }
145
-
146
- const baseVersion = versionRange.replace('.x', '');
147
- const expandedVersions = [];
148
-
149
- // For major.minor.x patterns, we'll deprecate specific known versions
150
- // This is safer than guessing version numbers
151
- return [versionRange]; // Keep as-is for npm deprecate command
152
- }
153
-
154
- // Main deprecation process
155
- async function deprecateVersions() {
156
- const status = getDeprecationStatus();
157
- const versionsToDeprecate = getVersionsToDeprecate();
158
- const currentVersion = packageJson.version;
159
-
160
- console.log('\nšŸ“Š Deprecation Status Summary:');
161
- console.log('=====================================');
162
- console.log(`šŸ“¦ Total Published Versions: ${status.published.length}`);
163
- console.log(`āœ… Already Deprecated: ${status.alreadyDeprecated.length}`);
164
- console.log(`šŸ”„ Not Deprecated: ${status.notDeprecated.length}`);
165
- console.log(`šŸŽÆ Current Version: ${currentVersion} (protected)`);
166
- console.log(`šŸ“‹ Target Deprecation Patterns: ${versionsToDeprecate.length}`);
167
- console.log('=====================================\n');
168
-
169
- if (status.errors.length > 0) {
170
- console.log('āš ļø Errors encountered:');
171
- status.errors.forEach(({ version, error }) => {
172
- console.log(` ${version}: ${error}`);
173
- });
174
- console.log('');
175
- }
176
-
177
- // Find versions that need to be deprecated
178
- const versionsNeedingDeprecation = [];
179
-
180
- for (const versionPattern of versionsToDeprecate) {
181
- // Skip current version
182
- if (versionPattern === currentVersion) {
183
- console.log(`ā­ļø Skipping current version ${versionPattern}`);
184
- continue;
185
- }
186
-
187
- // Check if this version pattern matches any published versions
188
- const matchingVersions = status.published.filter(v => {
189
- if (versionPattern.includes('x')) {
190
- // Handle version ranges like "1.0.x"
191
- const basePattern = versionPattern.replace('.x', '.');
192
- return v.startsWith(basePattern);
193
- } else {
194
- // Exact version match
195
- return v === versionPattern;
196
- }
197
- });
198
-
199
- if (matchingVersions.length === 0) {
200
- console.log(`āš ļø No published versions match pattern ${versionPattern}`);
201
- continue;
202
- }
203
-
204
- // Check which of these versions are not already deprecated
205
- const needingDeprecation = matchingVersions.filter(v =>
206
- v !== currentVersion && !status.alreadyDeprecated.includes(v)
207
- );
208
-
209
- if (needingDeprecation.length > 0) {
210
- versionsNeedingDeprecation.push(...needingDeprecation);
211
- console.log(`šŸ“‹ ${versionPattern}: ${needingDeprecation.length} versions need deprecation`);
212
- } else {
213
- console.log(`āœ… ${versionPattern}: All matching versions already deprecated`);
214
- }
215
- }
216
-
217
- if (versionsNeedingDeprecation.length === 0) {
218
- console.log('\nšŸŽ‰ All target versions are already deprecated!');
219
- console.log('=====================================');
220
- console.log('āœ… No action needed - deprecation is complete');
221
- console.log('=====================================');
222
- return;
223
- }
224
-
225
- console.log(`\n🚨 Ready to deprecate ${versionsNeedingDeprecation.length} versions:`);
226
- versionsNeedingDeprecation.forEach(version => {
227
- console.log(` • ${version}`);
228
- });
229
-
230
- // In dry-run mode, just show what would be done
231
- if (args.includes('--dry-run')) {
232
- console.log('\nšŸ” DRY RUN MODE - No actual deprecations will be made');
233
- console.log('=====================================');
234
- return;
235
- }
236
-
237
- // Confirm before proceeding
238
- if (!args.includes('--yes')) {
239
- console.log('\nāš ļø This will permanently deprecate versions on npm.');
240
- console.log(' Are you sure you want to continue?');
241
- console.log(' Run with --yes to proceed, or --dry-run to preview only.');
242
- return;
243
- }
244
-
245
- // Perform deprecations
246
- console.log('\nšŸš€ Starting deprecation process...');
247
- let successCount = 0;
248
- let failCount = 0;
249
-
250
- for (const version of versionsNeedingDeprecation) {
251
- if (deprecateVersion(version, deprecationMessage)) {
252
- successCount++;
253
- } else {
254
- failCount++;
255
- }
256
-
257
- // Small delay to avoid overwhelming npm registry
258
- await new Promise(resolve => setTimeout(resolve, 1000));
259
- }
260
-
261
- console.log('\n=====================================');
262
- console.log('šŸŽ‰ Deprecation Process Complete!');
263
- console.log('=====================================');
264
- console.log(`āœ… Successfully deprecated: ${successCount} versions`);
265
- console.log(`āŒ Failed to deprecate: ${failCount} versions`);
266
- console.log(`šŸ“Š Total processed: ${successCount + failCount} versions`);
267
- console.log('=====================================');
268
-
269
- if (failCount > 0) {
270
- console.log('\nāš ļø Some versions failed to deprecate. You may need to:');
271
- console.log(' 1. Check your npm permissions');
272
- console.log(' 2. Verify you are logged in with npm login');
273
- console.log(' 3. Try running the script again for failed versions');
274
- }
275
- }
276
-
277
- // Handle command line arguments
278
- const args = process.argv.slice(2);
279
-
280
- if (args.includes('--help') || args.includes('-h')) {
281
- console.log(`
282
- i18ntk Intelligent Version Deprecation Script
283
-
284
- Usage:
285
- node scripts/deprecate-versions.js [options]
286
-
287
- Options:
288
- --dry-run Show what would be deprecated without making changes
289
- --yes Confirm deprecation (required for actual deprecation)
290
- --help, -h Show this help message
291
-
292
- Description:
293
- This script intelligently manages version deprecations for i18ntk.
294
- It only deprecates versions that aren't already deprecated and
295
- provides admin control through deprecation-config.json.
296
-
297
- Configuration:
298
- Create deprecation-config.json to customize which versions to deprecate:
299
-
300
- {
301
- "versionsToDeprecate": ["1.0.x", "1.1.x", "1.8.0", "1.9.0"],
302
- "excludeVersions": ["1.5.0"],
303
- "customMessage": "Custom deprecation message"
304
- }
305
-
306
- Examples:
307
- node scripts/deprecate-versions.js --dry-run
308
- node scripts/deprecate-versions.js --yes
309
- `);
310
- process.exit(0);
311
- }
312
-
313
- // Run the deprecation process
314
- deprecateVersions().catch(error => {
315
- console.error('šŸ’„ Fatal error during deprecation process:', error);
316
- process.exit(1);
317
- });
@@ -1,84 +0,0 @@
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, '..', 'resources', 'i18n', '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 (!SecurityUtils.safeExistsSync(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 (!SecurityUtils.safeExistsSync(targetFile)) {
35
- const sourceContent = JSON.parse(SecurityUtils.safeReadFileSync(sourceFile, path.dirname(sourceFile), 'utf8'));
36
- const templateContent = createTemplateFromEnglish(sourceContent);
37
- SecurityUtils.safeWriteFileSync(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
- module.exports = { createLanguageTemplate };