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
@@ -1104,17 +1104,18 @@
1104
1104
  "warningProceedingWithoutFramework": "Fortfahren ohne erkanntes i18n-Framework."
1105
1105
  },
1106
1106
  "language": {
1107
- "title": "🌍 Sprache ändern",
1108
- "separator": "============================================================",
1109
- "current": "Aktuelle Sprache: {language}",
1110
- "available": "Verfügbare Sprachen:",
1111
- "languageOption": "{index}. {displayName}{current}",
1112
- "backToMainMenu": "Zurück zum Hauptmenü",
1113
- "prompt": "Wähle eine Sprache (0–8):",
1114
- "cancelled": "Sprachwechsel abgebrochen.",
1115
- "invalid": "Ungültige Auswahl. Bitte erneut versuchen.",
1116
- "changed": "Sprache geändert zu: {language}",
1117
- "pressEnterToContinue": "Drücke Enter, um fortzufahren..."
1107
+ "title": "🌍 Sprache ändern",
1108
+ "separator": "============================================================",
1109
+ "current": "Aktuelle Sprache: {language}",
1110
+ "available": "Verfügbare Sprachen:",
1111
+ "languageOption": "{index}. {displayName}{current}",
1112
+ "backToMainMenu": "Zurück zum Hauptmenü",
1113
+ "prompt": "Wähle eine Sprache (0–8):",
1114
+ "cancelled": "Sprachwechsel abgebrochen.",
1115
+ "invalid": "Ungültige Auswahl. Bitte erneut versuchen.",
1116
+ "changed": "Sprache geändert zu: {language}",
1117
+ "changeFailed": "Sprachwechsel fehlgeschlagen: {error}",
1118
+ "pressEnterToContinue": "Drücke Enter, um fortzufahren..."
1118
1119
  },
1119
1120
  "maintainLanguagePurity": {
1120
1121
  "workflow_title": "🚀 Workflow zur Wahrung der Sprachreinheit",
@@ -1104,17 +1104,18 @@
1104
1104
  "warningProceedingWithoutFramework": "Proceeding without detected i18n framework."
1105
1105
  },
1106
1106
  "language": {
1107
- "title": "🌍 Change Language",
1108
- "separator": "============================================================",
1109
- "current": "Current language: {language}",
1110
- "available": "Available Languages:",
1111
- "languageOption": "{index}. {displayName}{current}",
1112
- "backToMainMenu": "Back to Main Menu",
1113
- "prompt": "Select a language (0-8):",
1114
- "cancelled": "Language change cancelled.",
1115
- "invalid": "Invalid choice. Please try again.",
1116
- "changed": "Language changed to: {language}",
1117
- "pressEnterToContinue": "Press Enter to continue..."
1107
+ "title": "🌍 Change Language",
1108
+ "separator": "============================================================",
1109
+ "current": "Current language: {language}",
1110
+ "available": "Available Languages:",
1111
+ "languageOption": "{index}. {displayName}{current}",
1112
+ "backToMainMenu": "Back to Main Menu",
1113
+ "prompt": "Select a language (0-8):",
1114
+ "cancelled": "Language change cancelled.",
1115
+ "invalid": "Invalid choice. Please try again.",
1116
+ "changed": "Language changed to: {language}",
1117
+ "changeFailed": "Failed to change language: {error}",
1118
+ "pressEnterToContinue": "Press Enter to continue..."
1118
1119
  },
1119
1120
  "maintainLanguagePurity": {
1120
1121
  "workflow_title": "🚀 Language Purity Maintenance Workflow",
@@ -1104,17 +1104,18 @@
1104
1104
  "warningProceedingWithoutFramework": "Procediendo sin marco i18n detectado."
1105
1105
  },
1106
1106
  "language": {
1107
- "title": "🌍 Cambiar Idioma",
1108
- "separator": "============================================================",
1109
- "current": "Idioma actual: {language}",
1110
- "available": "Idiomas Disponibles:",
1111
- "languageOption": "{index}. {displayName}{current}",
1112
- "backToMainMenu": "Volver al Menú Principal",
1113
- "prompt": "Selecciona un idioma (0-8):",
1114
- "cancelled": "Cambio de idioma cancelado.",
1115
- "invalid": "Opción inválida. Por favor intenta de nuevo.",
1116
- "changed": "Idioma cambiado a: {language}",
1117
- "pressEnterToContinue": "Presiona Enter para continuar..."
1107
+ "title": "🌍 Cambiar Idioma",
1108
+ "separator": "============================================================",
1109
+ "current": "Idioma actual: {language}",
1110
+ "available": "Idiomas Disponibles:",
1111
+ "languageOption": "{index}. {displayName}{current}",
1112
+ "backToMainMenu": "Volver al Menú Principal",
1113
+ "prompt": "Selecciona un idioma (0-8):",
1114
+ "cancelled": "Cambio de idioma cancelado.",
1115
+ "invalid": "Opción inválida. Por favor intenta de nuevo.",
1116
+ "changed": "Idioma cambiado a: {language}",
1117
+ "changeFailed": "Error al cambiar el idioma: {error}",
1118
+ "pressEnterToContinue": "Presiona Enter para continuar..."
1118
1119
  },
1119
1120
  "maintainLanguagePurity": {
1120
1121
  "workflow_title": "🚀 Flujo de Trabajo de Mantenimiento de Pureza de Idioma",
@@ -1104,17 +1104,18 @@
1104
1104
  "warningProceedingWithoutFramework": "Poursuite sans framework i18n détecté."
1105
1105
  },
1106
1106
  "language": {
1107
- "title": "🌍 Changer la langue",
1108
- "separator": "============================================================",
1109
- "current": "Langue actuelle : {language}",
1110
- "available": "Langues disponibles :",
1111
- "languageOption": "{index}. {displayName}{current}",
1112
- "backToMainMenu": "Retour au menu principal",
1113
- "prompt": "Sélectionnez une langue (0-8) :",
1114
- "cancelled": "Changement de langue annulé.",
1115
- "invalid": "Choix invalide. Veuillez réessayer.",
1116
- "changed": "Langue changée en : {language}",
1117
- "pressEnterToContinue": "Appuyez sur Entrée pour continuer…"
1107
+ "title": "🌍 Changer la langue",
1108
+ "separator": "============================================================",
1109
+ "current": "Langue actuelle : {language}",
1110
+ "available": "Langues disponibles :",
1111
+ "languageOption": "{index}. {displayName}{current}",
1112
+ "backToMainMenu": "Retour au menu principal",
1113
+ "prompt": "Sélectionnez une langue (0-8) :",
1114
+ "cancelled": "Changement de langue annulé.",
1115
+ "invalid": "Choix invalide. Veuillez réessayer.",
1116
+ "changed": "Langue changée en : {language}",
1117
+ "changeFailed": "Échec du changement de langue : {error}",
1118
+ "pressEnterToContinue": "Appuyez sur Entrée pour continuer…"
1118
1119
  },
1119
1120
  "maintainLanguagePurity": {
1120
1121
  "workflow_title": "🚀 Flux de maintenance de la pureté linguistique",
@@ -1104,17 +1104,18 @@
1104
1104
  "warningProceedingWithoutFramework": "i18n フレームワークが検出されないまま続行します。"
1105
1105
  },
1106
1106
  "language": {
1107
- "title": "🌍 言語を変更",
1108
- "separator": "============================================================",
1109
- "current": "現在の言語: {language}",
1110
- "available": "利用可能な言語:",
1111
- "languageOption": "{index}。 {displayName}{current}",
1112
- "backToMainMenu": "メインメニューに戻る",
1113
- "prompt": "言語を選択してください (0-8):",
1114
- "cancelled": "言語変更がキャンセルされました。",
1115
- "invalid": "無効な選択です。もう一度お試しください。",
1116
- "changed": "言語が {language} に変更されました",
1117
- "pressEnterToContinue": "続行するにはEnterキーを押してください…"
1107
+ "title": "🌍 言語を変更",
1108
+ "separator": "============================================================",
1109
+ "current": "現在の言語: {language}",
1110
+ "available": "利用可能な言語:",
1111
+ "languageOption": "{index}。 {displayName}{current}",
1112
+ "backToMainMenu": "メインメニューに戻る",
1113
+ "prompt": "言語を選択してください (0-8):",
1114
+ "cancelled": "言語変更がキャンセルされました。",
1115
+ "invalid": "無効な選択です。もう一度お試しください。",
1116
+ "changed": "言語が {language} に変更されました",
1117
+ "changeFailed": "言語の変更に失敗しました: {error}",
1118
+ "pressEnterToContinue": "続行するにはEnterキーを押してください…"
1118
1119
  },
1119
1120
  "maintainLanguagePurity": {
1120
1121
  "workflow_title": "🚀 言語純度維持ワークフロー",
@@ -1104,17 +1104,18 @@
1104
1104
  "warningProceedingWithoutFramework": "Продолжаем без обнаружения платформы i18n."
1105
1105
  },
1106
1106
  "language": {
1107
- "title": "🌍 Сменить язык",
1108
- "separator": "============================================================",
1109
- "current": "Текущий язык: {language}",
1110
- "available": "Доступные языки:",
1111
- "languageOption": "{index}. {displayName}{current}",
1112
- "backToMainMenu": "Вернуться в главное меню",
1113
- "prompt": "Выберите язык (0-8):",
1114
- "cancelled": "Смена языка отменена.",
1115
- "invalid": "Неверный выбор. Пожалуйста, попробуйте снова.",
1116
- "changed": "Язык изменён на: {language}",
1117
- "pressEnterToContinue": "Нажмите Enter для продолжения..."
1107
+ "title": "🌍 Сменить язык",
1108
+ "separator": "============================================================",
1109
+ "current": "Текущий язык: {language}",
1110
+ "available": "Доступные языки:",
1111
+ "languageOption": "{index}. {displayName}{current}",
1112
+ "backToMainMenu": "Вернуться в главное меню",
1113
+ "prompt": "Выберите язык (0-8):",
1114
+ "cancelled": "Смена языка отменена.",
1115
+ "invalid": "Неверный выбор. Пожалуйста, попробуйте снова.",
1116
+ "changed": "Язык изменён на: {language}",
1117
+ "changeFailed": "Не удалось сменить язык: {error}",
1118
+ "pressEnterToContinue": "Нажмите Enter для продолжения..."
1118
1119
  },
1119
1120
  "maintainLanguagePurity": {
1120
1121
  "workflow_title": "🚀 Рабочий процесс поддержания чистоты языков",
@@ -1104,17 +1104,18 @@
1104
1104
  "warningProceedingWithoutFramework": "未检测到 i18n 框架即可继续。"
1105
1105
  },
1106
1106
  "language": {
1107
- "title": "🌍 切换语言",
1108
- "separator": "============================================================",
1109
- "current": "当前语言:{language}",
1110
- "available": "可用语言:",
1111
- "languageOption": "{index}。 {displayName}{current}",
1112
- "backToMainMenu": "返回主菜单",
1113
- "prompt": "请选择语言(0-8):",
1114
- "cancelled": "已取消语言切换。",
1115
- "invalid": "无效选择,请重试。",
1116
- "changed": "语言已切换为:{language}",
1117
- "pressEnterToContinue": "按 Enter 继续..."
1107
+ "title": "🌍 切换语言",
1108
+ "separator": "============================================================",
1109
+ "current": "当前语言:{language}",
1110
+ "available": "可用语言:",
1111
+ "languageOption": "{index}。 {displayName}{current}",
1112
+ "backToMainMenu": "返回主菜单",
1113
+ "prompt": "请选择语言(0-8):",
1114
+ "cancelled": "已取消语言切换。",
1115
+ "invalid": "无效选择,请重试。",
1116
+ "changed": "语言已切换为:{language}",
1117
+ "changeFailed": "切换语言失败:{error}",
1118
+ "pressEnterToContinue": "按 Enter 继续..."
1118
1119
  },
1119
1120
  "maintainLanguagePurity": {
1120
1121
  "workflow_title": "🚀 语言纯洁度维护工作流",
@@ -9,9 +9,11 @@ const path = require('path');
9
9
  const configManager = require('./config-manager');
10
10
  const SecurityUtils = require('./security');
11
11
  const {loadTranslations} = require('./i18n-helper');
12
- const SettingsManager = require('../settings/settings-manager');
13
- const { envManager } = require('./env-manager');
14
- const settingsManager = new SettingsManager();
12
+ const SettingsManager = require('../settings/settings-manager');
13
+ const { envManager } = require('./env-manager');
14
+ const { checkInitialized } = require('./init-helper');
15
+ const { closeGlobalReadline } = require('./cli');
16
+ const settingsManager = new SettingsManager();
15
17
 
16
18
  const { ask } = require('./cli');
17
19
 
@@ -132,10 +134,15 @@ async function getUnifiedConfig(scriptName, cliArgs = {}) {
132
134
  cfg.notTranslatedMarker ||
133
135
  cfg.processing?.notTranslatedMarker ||
134
136
  'NOT_TRANSLATED';
135
- const markerList = Array.isArray(rawMarkers) ? rawMarkers : [rawMarkers];
136
-
137
- const config = {
138
- ...cfg,
137
+ const markerList = Array.isArray(rawMarkers) ? rawMarkers : [rawMarkers];
138
+ const configuredBackupKeep = parseInt(cfg.backup?.maxBackups, 10);
139
+ const normalizedBackupMaxBackups = Number.isInteger(configuredBackupKeep)
140
+ ? Math.min(Math.max(configuredBackupKeep, 1), 3)
141
+ : 1;
142
+ const normalizedBackupLocation = cfg.backup?.location || './i18ntk-backups';
143
+
144
+ const config = {
145
+ ...cfg,
139
146
  sourceLanguage: cliArgs.sourceLanguage || cfg.sourceLanguage || 'en',
140
147
  uiLanguage: cliArgs.uiLanguage || cfg.uiLanguage || 'en',
141
148
  notTranslatedMarker: markerList[0],
@@ -144,11 +151,17 @@ async function getUnifiedConfig(scriptName, cliArgs = {}) {
144
151
  excludeFiles: cfg.excludeFiles || cfg.processing?.excludeFiles || ['.DS_Store', 'Thumbs.db'],
145
152
  excludeDirs: cfg.excludeDirs || cfg.processing?.excludeDirs || ['node_modules', '.next', '.git', 'dist', 'build'],
146
153
  strictMode: cliArgs.strictMode || cfg.strictMode || false,
147
- backupDir: path.join(settingsDir, 'backups'),
148
- tempDir: path.join(settingsDir, 'temp'),
149
- cacheDir: path.join(settingsDir, '.cache'),
150
- configDir: settingsDir,
151
- settings: {
154
+ backupDir: path.resolve(projectRoot, normalizedBackupLocation),
155
+ tempDir: path.join(settingsDir, 'temp'),
156
+ cacheDir: path.join(settingsDir, '.cache'),
157
+ configDir: settingsDir,
158
+ backup: {
159
+ ...(cfg.backup || {}),
160
+ enabled: cfg.backup?.enabled === true,
161
+ location: normalizedBackupLocation,
162
+ maxBackups: normalizedBackupMaxBackups
163
+ },
164
+ settings: {
152
165
  defaultLanguages: cfg.defaultLanguages || ['de', 'es', 'fr', 'ru'],
153
166
  processing: { ...cfg.processing },
154
167
  security: { ...cfg.security },
@@ -169,8 +182,8 @@ async function getUnifiedConfig(scriptName, cliArgs = {}) {
169
182
  * Get environment-specific configuration
170
183
  * @returns {object} Environment configuration
171
184
  */
172
- function getEnvironmentConfig() {
173
- const settings = require('../settings/settings-manager').getAllSettings();
185
+ function getEnvironmentConfig() {
186
+ const settings = settingsManager.getAllSettings();
174
187
  return {
175
188
  nodeEnv: settings.nodeEnv || 'production',
176
189
  isProduction: (settings.nodeEnv || 'production') === 'production',
@@ -425,7 +438,6 @@ function displayPaths(cfg = {}) {
425
438
  // Ensure project has been initialized with source language files
426
439
  async function ensureInitialized(cfg) {
427
440
  try {
428
- const { checkInitialized } = require('./init-helper');
429
441
  const sourceDir = cfg?.sourceDir || './locales';
430
442
  const sourceLanguage = cfg?.sourceLanguage || 'en';
431
443
 
@@ -445,7 +457,6 @@ async function ensureInitialized(cfg) {
445
457
 
446
458
  const langDir = path.join(sourceDir, sourceLanguage);
447
459
  const answer = await ask(`Source language files not found in ${langDir}. Run initialization now? (y/N) `);
448
- const { closeGlobalReadline } = require('./cli');
449
460
  closeGlobalReadline();
450
461
 
451
462
  if (answer.trim().toLowerCase().startsWith('y')) {
@@ -169,13 +169,14 @@ const DEFAULT_CONFIG = {
169
169
  "memoryPooling": true,
170
170
  "stringInterning": true
171
171
  },
172
- "backup": {
173
- "enabled": false,
174
- "singleFileMode": false,
175
- "singleBackupFile": "i18ntk-central-backup.json",
176
- "retentionDays": 30,
177
- "maxBackups": 100
178
- },
172
+ "backup": {
173
+ "enabled": false,
174
+ "location": "./i18ntk-backups",
175
+ "singleFileMode": false,
176
+ "singleBackupFile": "i18ntk-central-backup.json",
177
+ "retentionDays": 30,
178
+ "maxBackups": 1
179
+ },
179
180
  "security": {
180
181
  "adminPinEnabled": false,
181
182
  "adminPinPromptOnInit": true,