i18ntk 1.0.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 (86) hide show
  1. package/CHANGELOG.md +401 -0
  2. package/LICENSE +21 -0
  3. package/README.md +507 -0
  4. package/dev/README.md +37 -0
  5. package/dev/debug/README.md +30 -0
  6. package/dev/debug/complete-console-translations.js +295 -0
  7. package/dev/debug/console-key-checker.js +408 -0
  8. package/dev/debug/console-translations.js +335 -0
  9. package/dev/debug/debugger.js +408 -0
  10. package/dev/debug/export-missing-keys.js +432 -0
  11. package/dev/debug/final-normalize.js +236 -0
  12. package/dev/debug/find-extra-keys.js +68 -0
  13. package/dev/debug/normalize-locales.js +153 -0
  14. package/dev/debug/refactor-locales.js +240 -0
  15. package/dev/debug/reorder-locales.js +85 -0
  16. package/dev/debug/replace-hardcoded-console.js +378 -0
  17. package/docs/INSTALLATION.md +449 -0
  18. package/docs/README.md +222 -0
  19. package/docs/TODO_ROADMAP.md +279 -0
  20. package/docs/api/API_REFERENCE.md +377 -0
  21. package/docs/api/COMPONENTS.md +492 -0
  22. package/docs/api/CONFIGURATION.md +651 -0
  23. package/docs/api/NPM_PUBLISHING_GUIDE.md +434 -0
  24. package/docs/debug/DEBUG_README.md +30 -0
  25. package/docs/debug/DEBUG_TOOLS.md +494 -0
  26. package/docs/development/AGENTS.md +351 -0
  27. package/docs/development/DEVELOPMENT_RULES.md +165 -0
  28. package/docs/development/DEV_README.md +37 -0
  29. package/docs/release-notes/RELEASE_NOTES_v1.0.0.md +173 -0
  30. package/docs/release-notes/RELEASE_NOTES_v1.6.0.md +141 -0
  31. package/docs/release-notes/RELEASE_NOTES_v1.6.1.md +185 -0
  32. package/docs/release-notes/RELEASE_NOTES_v1.6.3.md +199 -0
  33. package/docs/reports/ANALYSIS_README.md +17 -0
  34. package/docs/reports/CONSOLE_MISMATCH_BUG_REPORT_v1.5.0.md +181 -0
  35. package/docs/reports/SIZING_README.md +18 -0
  36. package/docs/reports/SUMMARY_README.md +18 -0
  37. package/docs/reports/TRANSLATION_BUG_REPORT_v1.5.0.md +129 -0
  38. package/docs/reports/USAGE_README.md +18 -0
  39. package/docs/reports/VALIDATION_README.md +18 -0
  40. package/locales/de/auth.json +3 -0
  41. package/locales/de/common.json +16 -0
  42. package/locales/de/pagination.json +6 -0
  43. package/locales/en/auth.json +3 -0
  44. package/locales/en/common.json +16 -0
  45. package/locales/en/pagination.json +6 -0
  46. package/locales/es/auth.json +3 -0
  47. package/locales/es/common.json +16 -0
  48. package/locales/es/pagination.json +6 -0
  49. package/locales/fr/auth.json +3 -0
  50. package/locales/fr/common.json +16 -0
  51. package/locales/fr/pagination.json +6 -0
  52. package/locales/ru/auth.json +3 -0
  53. package/locales/ru/common.json +16 -0
  54. package/locales/ru/pagination.json +6 -0
  55. package/main/i18ntk-analyze.js +625 -0
  56. package/main/i18ntk-autorun.js +461 -0
  57. package/main/i18ntk-complete.js +494 -0
  58. package/main/i18ntk-init.js +686 -0
  59. package/main/i18ntk-manage.js +848 -0
  60. package/main/i18ntk-sizing.js +557 -0
  61. package/main/i18ntk-summary.js +671 -0
  62. package/main/i18ntk-usage.js +1282 -0
  63. package/main/i18ntk-validate.js +762 -0
  64. package/main/ui-i18n.js +332 -0
  65. package/package.json +152 -0
  66. package/scripts/fix-missing-translation-keys.js +214 -0
  67. package/scripts/verify-package.js +168 -0
  68. package/ui-locales/de.json +637 -0
  69. package/ui-locales/en.json +688 -0
  70. package/ui-locales/es.json +637 -0
  71. package/ui-locales/fr.json +637 -0
  72. package/ui-locales/ja.json +637 -0
  73. package/ui-locales/ru.json +637 -0
  74. package/ui-locales/zh.json +637 -0
  75. package/utils/admin-auth.js +317 -0
  76. package/utils/admin-cli.js +353 -0
  77. package/utils/admin-pin.js +409 -0
  78. package/utils/detect-language-mismatches.js +454 -0
  79. package/utils/i18n-helper.js +128 -0
  80. package/utils/maintain-language-purity.js +433 -0
  81. package/utils/native-translations.js +478 -0
  82. package/utils/security.js +384 -0
  83. package/utils/test-complete-system.js +356 -0
  84. package/utils/test-console-i18n.js +402 -0
  85. package/utils/translate-mismatches.js +571 -0
  86. package/utils/validate-language-purity.js +531 -0
@@ -0,0 +1,378 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const UIi18n = require('../../main/ui-i18n');
4
+
5
+ class HardcodedConsoleReplacer {
6
+ constructor() {
7
+ this.ui = new UIi18n();
8
+ this.projectRoot = path.join(__dirname, '..', '..');
9
+ this.replacements = new Map();
10
+ this.dryRun = process.argv.includes('--dry-run');
11
+ this.verbose = process.argv.includes('--verbose');
12
+ this.stats = {
13
+ filesProcessed: 0,
14
+ replacementsMade: 0,
15
+ filesModified: 0
16
+ };
17
+
18
+ this.initializeReplacements();
19
+ }
20
+
21
+ initializeReplacements() {
22
+ // Common console message patterns and their translation keys
23
+ this.replacements.set(
24
+ /console\.log\('⚠️\s*No package\.json found\. This toolkit works independently but is recommended to be used with i18n frameworks\.'/g,
25
+ "console.log(this.ui.t('init.warnings.noPackageJson'))"
26
+ );
27
+
28
+ this.replacements.set(
29
+ /console\.log\('💡 No i18n framework detected\. Consider installing one of:'/g,
30
+ "console.log(this.ui.t('init.suggestions.noFramework'))"
31
+ );
32
+
33
+ this.replacements.set(
34
+ /console\.log\('\s*- react-i18next \(for React\)'/g,
35
+ "console.log(this.ui.t('init.frameworks.react'))"
36
+ );
37
+
38
+ this.replacements.set(
39
+ /console\.log\('\s*- vue-i18n \(for Vue\)'/g,
40
+ "console.log(this.ui.t('init.frameworks.vue'))"
41
+ );
42
+
43
+ this.replacements.set(
44
+ /console\.log\('\s*- i18next \(universal\)'/g,
45
+ "console.log(this.ui.t('init.frameworks.i18next'))"
46
+ );
47
+
48
+ this.replacements.set(
49
+ /console\.log\('\s*- @nuxtjs\/i18n \(for Nuxt\)'/g,
50
+ "console.log(this.ui.t('init.frameworks.nuxt'))"
51
+ );
52
+
53
+ this.replacements.set(
54
+ /console\.log\('\s*- svelte-i18n \(for Svelte\)'/g,
55
+ "console.log(this.ui.t('init.frameworks.svelte'))"
56
+ );
57
+
58
+ this.replacements.set(
59
+ /console\.log\('⚠️\s*Could not read package\.json'/g,
60
+ "console.log(this.ui.t('init.errors.packageJsonRead'))"
61
+ );
62
+
63
+ this.replacements.set(
64
+ /console\.log\('🎛️\s*I18N Management Toolkit'/g,
65
+ "console.log(this.ui.t('menu.title'))"
66
+ );
67
+
68
+ this.replacements.set(
69
+ /console\.log\('\\n📦 Please install an i18n framework and try again\.'/g,
70
+ "console.log(this.ui.t('init.errors.noFramework'))"
71
+ );
72
+
73
+ this.replacements.set(
74
+ /console\.log\('💡 Recommended: npm install react-i18next \(or your preferred framework\)'/g,
75
+ "console.log(this.ui.t('init.suggestions.installFramework'))"
76
+ );
77
+
78
+ this.replacements.set(
79
+ /console\.log\('\\n🚀 Starting automated workflow\.\.\.'\);/g,
80
+ "console.log(this.ui.t('workflow.starting'));"
81
+ );
82
+
83
+ this.replacements.set(
84
+ /console\.log\('\\n✅ Workflow completed successfully!'\);/g,
85
+ "console.log(this.ui.t('workflow.completed'));"
86
+ );
87
+
88
+ this.replacements.set(
89
+ /console\.log\('📋 Check the generated reports in the i18ntk-reports directory\.'\);/g,
90
+ "console.log(this.ui.t('workflow.checkReports'));"
91
+ );
92
+
93
+ this.replacements.set(
94
+ /console\.log\('\\n📝 Returning to main menu\.\.\.'\);/g,
95
+ "console.log(this.ui.t('menu.returning'));"
96
+ );
97
+
98
+ this.replacements.set(
99
+ /console\.log\('\\n📝 Workflow completed\. Exiting\.\.\.'\);/g,
100
+ "console.log(this.ui.t('workflow.exitingCompleted'));"
101
+ );
102
+
103
+ this.replacements.set(
104
+ /console\.log\('\\n✅ Operation completed successfully!'\);/g,
105
+ "console.log(this.ui.t('operations.completed'));"
106
+ );
107
+
108
+ this.replacements.set(
109
+ /console\.log\('\\n🔐 Admin authentication required'\);/g,
110
+ "console.log(this.ui.t('admin.authRequired'));"
111
+ );
112
+
113
+ this.replacements.set(
114
+ /console\.log\('❌ Invalid PIN\. Access denied\.'\);/g,
115
+ "console.log(this.ui.t('admin.invalidPin'));"
116
+ );
117
+
118
+ this.replacements.set(
119
+ /console\.log\('✅ Authentication successful\.'\);/g,
120
+ "console.log(this.ui.t('admin.authSuccess'));"
121
+ );
122
+
123
+ this.replacements.set(
124
+ /console\.log\('\\n📊 Generating Status Summary\.\.\.'\);/g,
125
+ "console.log(this.ui.t('status.generating'));"
126
+ );
127
+
128
+ this.replacements.set(
129
+ /console\.log\('✅ Status summary completed successfully!'\);/g,
130
+ "console.log(this.ui.t('status.completed'));"
131
+ );
132
+
133
+ this.replacements.set(
134
+ /console\.log\('\\n📝 Status summary completed\. Exiting\.\.\.'\);/g,
135
+ "console.log(this.ui.t('status.exitingCompleted'));"
136
+ );
137
+
138
+ this.replacements.set(
139
+ /console\.log\('\\n📝 Error occurred\. Exiting\.\.\.'\);/g,
140
+ "console.log(this.ui.t('common.errorExiting'));"
141
+ );
142
+
143
+ this.replacements.set(
144
+ /console\.log\('❌ Invalid option\. Please try again\.'\);/g,
145
+ "console.log(this.ui.t('menu.invalidChoice'));"
146
+ );
147
+
148
+ this.replacements.set(
149
+ /console\.log\('\\n🗑️\s*Deletion Options:'\);/g,
150
+ "console.log(this.ui.t('delete.options.title'));"
151
+ );
152
+
153
+ this.replacements.set(
154
+ /console\.log\('\s*1\. Delete all reports'\);/g,
155
+ "console.log(this.ui.t('delete.options.all'));"
156
+ );
157
+
158
+ this.replacements.set(
159
+ /console\.log\('\s*2\. Keep last 3 reports \(delete older ones\)'\);/g,
160
+ "console.log(this.ui.t('delete.options.keepLast3'));"
161
+ );
162
+
163
+ this.replacements.set(
164
+ /console\.log\('\s*0\. Cancel'\);/g,
165
+ "console.log(this.ui.t('delete.options.cancel'));"
166
+ );
167
+
168
+ this.replacements.set(
169
+ /console\.log\('❌ Operation cancelled\.'\);/g,
170
+ "console.log(this.ui.t('operations.cancelled'));"
171
+ );
172
+
173
+ this.replacements.set(
174
+ /console\.log\('❌ Invalid option\.'\);/g,
175
+ "console.log(this.ui.t('menu.invalidOption'));"
176
+ );
177
+
178
+ this.replacements.set(
179
+ /console\.log\('✅ No files to delete\.'\);/g,
180
+ "console.log(this.ui.t('delete.noFiles'));"
181
+ );
182
+
183
+ this.replacements.set(
184
+ /console\.log\('\\n🌍 CHANGE UI LANGUAGE'\);/g,
185
+ "console.log(this.ui.t('language.changeTitle'));"
186
+ );
187
+
188
+ this.replacements.set(
189
+ /console\.log\('Available languages:'\);/g,
190
+ "console.log(this.ui.t('language.available'));"
191
+ );
192
+
193
+ this.replacements.set(
194
+ /console\.log\('❌ Invalid selection\.'\);/g,
195
+ "console.log(this.ui.t('language.invalidSelection'));"
196
+ );
197
+ }
198
+
199
+ async run() {
200
+ console.log('🔧 HARDCODED CONSOLE REPLACER');
201
+ console.log('============================================================');
202
+
203
+ if (this.dryRun) {
204
+ console.log('🧪 DRY RUN MODE - No files will be modified');
205
+ }
206
+ console.log('');
207
+
208
+ try {
209
+ const jsFiles = await this.findJavaScriptFiles();
210
+ console.log(`🔍 Found ${jsFiles.length} JavaScript files to process`);
211
+ console.log('');
212
+
213
+ for (const filePath of jsFiles) {
214
+ await this.processFile(filePath);
215
+ }
216
+
217
+ this.generateReport();
218
+
219
+ } catch (error) {
220
+ console.error('❌ Error during console replacement:', error.message);
221
+ process.exit(1);
222
+ }
223
+ }
224
+
225
+ async findJavaScriptFiles() {
226
+ const files = [];
227
+ const excludeDirs = ['node_modules', '.git', 'reports', 'i18ntk-reports'];
228
+
229
+ const scanDirectory = (dir) => {
230
+ const items = fs.readdirSync(dir);
231
+
232
+ for (const item of items) {
233
+ const fullPath = path.join(dir, item);
234
+ const stat = fs.statSync(fullPath);
235
+
236
+ if (stat.isDirectory()) {
237
+ if (!excludeDirs.includes(item)) {
238
+ scanDirectory(fullPath);
239
+ }
240
+ } else if (item.endsWith('.js') && !item.includes('.min.')) {
241
+ files.push(fullPath);
242
+ }
243
+ }
244
+ };
245
+
246
+ scanDirectory(this.projectRoot);
247
+ return files;
248
+ }
249
+
250
+ async processFile(filePath) {
251
+ try {
252
+ const content = fs.readFileSync(filePath, 'utf8');
253
+ let modifiedContent = content;
254
+ let fileModified = false;
255
+ let replacementsInFile = 0;
256
+
257
+ // Apply all replacements
258
+ for (const [pattern, replacement] of this.replacements) {
259
+ const matches = modifiedContent.match(pattern);
260
+ if (matches) {
261
+ modifiedContent = modifiedContent.replace(pattern, replacement);
262
+ replacementsInFile += matches.length;
263
+ fileModified = true;
264
+ }
265
+ }
266
+
267
+ // Check if we need to add UIi18n import
268
+ if (fileModified && !modifiedContent.includes('UIi18n')) {
269
+ const relativePath = path.relative(path.dirname(filePath), path.join(this.projectRoot, 'ui-i18n.js'));
270
+ const importStatement = `const UIi18n = require('${relativePath}');\n`;
271
+
272
+ // Add import after existing requires or at the top
273
+ const requireRegex = /(const .* = require\(.*\);\n)+/;
274
+ if (requireRegex.test(modifiedContent)) {
275
+ modifiedContent = modifiedContent.replace(requireRegex, (match) => match + importStatement);
276
+ } else {
277
+ modifiedContent = importStatement + modifiedContent;
278
+ }
279
+
280
+ // Add UIi18n initialization in constructor or at the beginning of main functions
281
+ if (modifiedContent.includes('class ') && modifiedContent.includes('constructor')) {
282
+ // Add to constructor
283
+ modifiedContent = modifiedContent.replace(
284
+ /(constructor\([^)]*\)\s*{)/,
285
+ '$1\n this.ui = new UIi18n();'
286
+ );
287
+ } else if (modifiedContent.includes('function ') || modifiedContent.includes('async function')) {
288
+ // Add at the beginning of main function
289
+ const functionMatch = modifiedContent.match(/((?:async )?function [^{]+{)/)
290
+ if (functionMatch) {
291
+ modifiedContent = modifiedContent.replace(
292
+ functionMatch[0],
293
+ functionMatch[0] + '\n const ui = new UIi18n();'
294
+ );
295
+ // Update console.log calls to use ui instead of this.ui
296
+ modifiedContent = modifiedContent.replace(/this\.ui\.t\(/g, 'ui.t(');
297
+ }
298
+ } else {
299
+ // Add at the top level
300
+ modifiedContent = modifiedContent.replace(
301
+ /(const UIi18n = require\(.*\);\n)/,
302
+ '$1const ui = new UIi18n();\n'
303
+ );
304
+ // Update console.log calls to use ui instead of this.ui
305
+ modifiedContent = modifiedContent.replace(/this\.ui\.t\(/g, 'ui.t(');
306
+ }
307
+ }
308
+
309
+ if (fileModified) {
310
+ this.stats.filesModified++;
311
+ this.stats.replacementsMade += replacementsInFile;
312
+
313
+ if (this.verbose) {
314
+ console.log(`📝 ${path.relative(this.projectRoot, filePath)}: ${replacementsInFile} replacements`);
315
+ }
316
+
317
+ if (!this.dryRun) {
318
+ fs.writeFileSync(filePath, modifiedContent, 'utf8');
319
+ }
320
+ }
321
+
322
+ this.stats.filesProcessed++;
323
+
324
+ } catch (error) {
325
+ console.error(`❌ Error processing ${filePath}:`, error.message);
326
+ }
327
+ }
328
+
329
+ generateReport() {
330
+ console.log('');
331
+ console.log('📊 REPLACEMENT SUMMARY');
332
+ console.log('============================================================');
333
+ console.log(`📁 Files processed: ${this.stats.filesProcessed}`);
334
+ console.log(`📝 Files modified: ${this.stats.filesModified}`);
335
+ console.log(`🔄 Total replacements: ${this.stats.replacementsMade}`);
336
+ console.log('');
337
+
338
+ if (this.stats.replacementsMade > 0) {
339
+ if (this.dryRun) {
340
+ console.log('💡 NEXT STEPS:');
341
+ console.log('------------------------------------------------------------');
342
+ console.log('🔧 Run without --dry-run to apply changes:');
343
+ console.log(' node replace-hardcoded-console.js');
344
+ } else {
345
+ console.log('✅ All hardcoded console messages have been replaced with translation keys!');
346
+ console.log('🌐 Your application now supports full internationalization.');
347
+ }
348
+ } else {
349
+ console.log('🎉 No hardcoded console messages found! Your code is already internationalized.');
350
+ }
351
+
352
+ console.log('');
353
+ }
354
+ }
355
+
356
+ // Show help
357
+ if (process.argv.includes('--help')) {
358
+ console.log('Replace hardcoded console.log statements with translation keys\n');
359
+ console.log('USAGE:');
360
+ console.log(' node replace-hardcoded-console.js [options]\n');
361
+ console.log('OPTIONS:');
362
+ console.log(' --dry-run Preview changes without modifying files');
363
+ console.log(' --verbose Show detailed progress');
364
+ console.log(' --help Show this help message\n');
365
+ console.log('EXAMPLES:');
366
+ console.log(' node replace-hardcoded-console.js --dry-run');
367
+ console.log(' node replace-hardcoded-console.js --verbose');
368
+ console.log(' node replace-hardcoded-console.js');
369
+ process.exit(0);
370
+ }
371
+
372
+ // Run the replacer
373
+ if (require.main === module) {
374
+ const replacer = new HardcodedConsoleReplacer();
375
+ replacer.run().catch(console.error);
376
+ }
377
+
378
+ module.exports = { HardcodedConsoleReplacer };