i18ntk 1.0.0 → 1.0.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/CHANGELOG.md +16 -1
- package/README.md +1 -1
- package/package.json +4 -2
- package/settings/admin-config.json +7 -0
- package/settings/settings-cli.js +1021 -0
- package/settings/settings-manager.js +596 -0
- package/settings/user-config.json +97 -0
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings Manager Module
|
|
3
|
+
* Handles loading, saving, and managing user configuration settings
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
class SettingsManager {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.configFile = path.join(__dirname, 'user-config.json');
|
|
12
|
+
this.defaultConfig = {
|
|
13
|
+
// UI Language Settings
|
|
14
|
+
language: 'en', // Default: 'en' | Options: 'en', 'de', 'es', 'fr', 'ru', 'ja', 'zh'
|
|
15
|
+
|
|
16
|
+
// File Size Limits
|
|
17
|
+
sizeLimit: null, // Default: null (no limit) | Example: 1048576 (1MB in bytes)
|
|
18
|
+
|
|
19
|
+
// Directory Configuration
|
|
20
|
+
sourceDir: './locales', // Default: './locales' | Example: './src/i18n/locales'
|
|
21
|
+
sourceLanguage: 'en', // Default: 'en' | Recommended: Use your primary development language
|
|
22
|
+
defaultLanguages: ['de', 'es', 'fr', 'ru'], // Default target languages | Example: ['de', 'es', 'fr', 'ru', 'ja', 'zh']
|
|
23
|
+
outputDir: './i18ntk-reports', // Default: './i18ntk-reports' | Example: './reports/i18n'
|
|
24
|
+
|
|
25
|
+
// Report Settings
|
|
26
|
+
reportLanguage: 'auto', // Default: 'auto' (matches UI language) | Options: 'auto', 'en', 'de', 'es', 'fr', 'ru', 'ja', 'zh'
|
|
27
|
+
|
|
28
|
+
// UI Preferences
|
|
29
|
+
theme: 'light', // Default: 'light' | Options: 'light', 'dark'
|
|
30
|
+
|
|
31
|
+
// Behavior Settings
|
|
32
|
+
autoSave: true, // Default: true | Automatically save settings changes
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
// Notification Settings
|
|
37
|
+
notifications: {
|
|
38
|
+
enabled: true, // Default: true | Enable/disable all notifications
|
|
39
|
+
types: {
|
|
40
|
+
success: true, // Show success notifications (e.g., "Translation completed")
|
|
41
|
+
warnings: true, // Show warning notifications (e.g., "Missing translations found")
|
|
42
|
+
errors: true, // Show error notifications (e.g., "File not found")
|
|
43
|
+
progress: true // Show progress notifications during long operations
|
|
44
|
+
},
|
|
45
|
+
sound: false, // Default: false | Play notification sounds
|
|
46
|
+
desktop: false // Default: false | Show desktop notifications (requires permission)
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
// Date and Time Formatting
|
|
51
|
+
dateFormat: 'DD/MM/YYYY', // Default: 'DD/MM/YYYY' | Options: 'DD/MM/YYYY', 'MM/DD/YYYY', 'YYYY-MM-DD', 'DD.MM.YYYY'
|
|
52
|
+
timeFormat: '24h', // Default: '24h' | Options: '24h', '12h'
|
|
53
|
+
timezone: 'auto', // Default: 'auto' (system timezone) | Example: 'UTC', 'Europe/London', 'America/New_York'
|
|
54
|
+
|
|
55
|
+
// Processing Settings
|
|
56
|
+
processing: {
|
|
57
|
+
notTranslatedMarker: 'NOT_TRANSLATED', // Default marker for untranslated content
|
|
58
|
+
excludeFiles: ['.DS_Store', 'Thumbs.db', '*.tmp'], // Files to ignore during processing
|
|
59
|
+
excludeDirs: ['node_modules', '.git', 'dist', 'build'], // Directories to ignore
|
|
60
|
+
includeExtensions: ['.js', '.jsx', '.ts', '.tsx', '.vue', '.svelte'], // File extensions to scan
|
|
61
|
+
strictMode: false, // Default: false | Enable strict validation (fails on warnings)
|
|
62
|
+
defaultLanguages: ['de', 'es', 'fr', 'ru'], // Languages to create when initializing
|
|
63
|
+
translationPatterns: [ // Patterns to detect translation keys in code
|
|
64
|
+
/t\(['"`]([^'"`]+)['"`]\)/g, // t('key')
|
|
65
|
+
/\$t\(['"`]([^'"`]+)['"`]\)/g, // $t('key')
|
|
66
|
+
/i18n\.t\(['"`]([^'"`]+)['"`]\)/g // i18n.t('key')
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
// Advanced Performance Settings
|
|
71
|
+
advanced: {
|
|
72
|
+
batchSize: 100, // Default: 100 | Recommended: 50-200 | Number of items processed per batch
|
|
73
|
+
maxConcurrentFiles: 10, // Default: 10 | Recommended: 5-20 | Maximum files processed simultaneously
|
|
74
|
+
enableProgressBars: true, // Default: true | Show progress bars for long operations
|
|
75
|
+
enableColorOutput: true, // Default: true | Use colored console output
|
|
76
|
+
strictMode: false, // Default: false | Enable strict validation mode
|
|
77
|
+
enableAuditLog: false, // Default: false | Track all translation changes (creates audit.log)
|
|
78
|
+
backupBeforeChanges: true, // Default: true | Create backups before modifications
|
|
79
|
+
validateOnSave: true, // Default: true | Auto-validate translations after saving
|
|
80
|
+
sizingThreshold: 50, // Default: 50% | Threshold for size variation warnings
|
|
81
|
+
sizingFormat: 'table', // Default: 'table' | Options: 'table', 'json', 'csv'
|
|
82
|
+
memoryLimit: '512MB', // Default: '512MB' | Memory limit for large file processing
|
|
83
|
+
timeout: 30000 // Default: 30000ms (30s) | Timeout for individual operations
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
// Security & Admin Settings
|
|
87
|
+
security: {
|
|
88
|
+
adminPinEnabled: false,
|
|
89
|
+
adminPinPromptOnInit: false,
|
|
90
|
+
keepAuthenticatedUntilExit: true,
|
|
91
|
+
sessionTimeout: 30,
|
|
92
|
+
maxFailedAttempts: 3,
|
|
93
|
+
lockoutDuration: 15,
|
|
94
|
+
enablePathValidation: true,
|
|
95
|
+
maxFileSize: 10 * 1024 * 1024, // 10MB
|
|
96
|
+
allowedExtensions: ['.json', '.js', '.jsx', '.ts', '.tsx', '.vue', '.svelte'],
|
|
97
|
+
notTranslatedMarker: '[NOT TRANSLATED]',
|
|
98
|
+
excludeFiles: ['node_modules', '.git', 'dist', 'build'],
|
|
99
|
+
strictMode: false
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
// Debug & Development Settings
|
|
103
|
+
debug: {
|
|
104
|
+
enabled: false, // Default: false | Enable debug mode
|
|
105
|
+
showSecurityLogs: false, // Default: false | Show security console logs when debug mode is enabled
|
|
106
|
+
verboseLogging: false, // Default: false | Enable verbose logging for debugging
|
|
107
|
+
logLevel: 'info', // Default: 'info' | Options: 'error', 'warn', 'info', 'debug'
|
|
108
|
+
saveDebugLogs: false, // Default: false | Save debug logs to file
|
|
109
|
+
debugLogPath: './debug.log' // Default: './debug.log' | Path for debug log file
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
this.settings = this.loadSettings();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Load settings from file or return default settings
|
|
117
|
+
* @returns {object} Settings object
|
|
118
|
+
*/
|
|
119
|
+
loadSettings() {
|
|
120
|
+
try {
|
|
121
|
+
if (fs.existsSync(this.configFile)) {
|
|
122
|
+
const content = fs.readFileSync(this.configFile, 'utf8');
|
|
123
|
+
const loadedSettings = JSON.parse(content);
|
|
124
|
+
// Merge with defaults to ensure all properties exist
|
|
125
|
+
return this.mergeWithDefaults(loadedSettings);
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error('❌ Error loading settings:', error.message);
|
|
129
|
+
}
|
|
130
|
+
return { ...this.defaultConfig };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Merge loaded settings with defaults to ensure all properties exist
|
|
135
|
+
* @param {object} loadedSettings - Settings loaded from file
|
|
136
|
+
* @returns {object} Merged settings
|
|
137
|
+
*/
|
|
138
|
+
mergeWithDefaults(loadedSettings) {
|
|
139
|
+
const merged = { ...this.defaultConfig, ...loadedSettings };
|
|
140
|
+
|
|
141
|
+
// Ensure nested objects are properly merged
|
|
142
|
+
if (loadedSettings.notifications) {
|
|
143
|
+
merged.notifications = {
|
|
144
|
+
...this.defaultConfig.notifications,
|
|
145
|
+
...loadedSettings.notifications,
|
|
146
|
+
types: {
|
|
147
|
+
...this.defaultConfig.notifications.types,
|
|
148
|
+
...(loadedSettings.notifications.types || {})
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (loadedSettings.processing) {
|
|
154
|
+
merged.processing = { ...this.defaultConfig.processing, ...loadedSettings.processing };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (loadedSettings.advanced) {
|
|
158
|
+
merged.advanced = { ...this.defaultConfig.advanced, ...loadedSettings.advanced };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return merged;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Save settings to file
|
|
166
|
+
* @param {object} newSettings - Settings to save
|
|
167
|
+
* @returns {boolean} Success status
|
|
168
|
+
*/
|
|
169
|
+
saveSettings(newSettings = null) {
|
|
170
|
+
try {
|
|
171
|
+
const settingsToSave = newSettings || this.settings;
|
|
172
|
+
|
|
173
|
+
// Validate settings before saving
|
|
174
|
+
if (!this.validateSettings(settingsToSave)) {
|
|
175
|
+
throw new Error('Invalid settings provided');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Create backup if enabled
|
|
179
|
+
if (settingsToSave.advanced?.backupBeforeChanges) {
|
|
180
|
+
this.createBackup();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
fs.writeFileSync(this.configFile, JSON.stringify(settingsToSave, null, 2), 'utf8');
|
|
184
|
+
this.settings = settingsToSave;
|
|
185
|
+
return true;
|
|
186
|
+
} catch (error) {
|
|
187
|
+
console.error('❌ Error saving settings:', error.message);
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Get current settings
|
|
194
|
+
* @returns {object} Current settings
|
|
195
|
+
*/
|
|
196
|
+
getSettings() {
|
|
197
|
+
return { ...this.settings };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Get a specific setting value
|
|
202
|
+
* @param {string} key - Setting key (supports dot notation)
|
|
203
|
+
* @returns {any} Setting value
|
|
204
|
+
*/
|
|
205
|
+
getSetting(key) {
|
|
206
|
+
const keys = key.split('.');
|
|
207
|
+
let value = this.settings;
|
|
208
|
+
|
|
209
|
+
for (const k of keys) {
|
|
210
|
+
if (value && typeof value === 'object' && k in value) {
|
|
211
|
+
value = value[k];
|
|
212
|
+
} else {
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Set a specific setting value
|
|
222
|
+
* @param {string} key - Setting key (supports dot notation)
|
|
223
|
+
* @param {any} value - Setting value
|
|
224
|
+
* @returns {boolean} Success status
|
|
225
|
+
*/
|
|
226
|
+
setSetting(key, value) {
|
|
227
|
+
try {
|
|
228
|
+
const keys = key.split('.');
|
|
229
|
+
let current = this.settings;
|
|
230
|
+
|
|
231
|
+
// Navigate to the parent object
|
|
232
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
233
|
+
const k = keys[i];
|
|
234
|
+
if (!(k in current) || typeof current[k] !== 'object') {
|
|
235
|
+
current[k] = {};
|
|
236
|
+
}
|
|
237
|
+
current = current[k];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Set the value
|
|
241
|
+
current[keys[keys.length - 1]] = value;
|
|
242
|
+
|
|
243
|
+
// Auto-save if enabled
|
|
244
|
+
if (this.settings.autoSave) {
|
|
245
|
+
return this.saveSettings();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return true;
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.error('❌ Error setting value:', error.message);
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Reset settings to defaults
|
|
257
|
+
* @returns {boolean} Success status
|
|
258
|
+
*/
|
|
259
|
+
resetToDefaults() {
|
|
260
|
+
this.settings = { ...this.defaultConfig };
|
|
261
|
+
return this.saveSettings();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Validate settings object
|
|
266
|
+
* @param {object} settings - Settings to validate
|
|
267
|
+
* @returns {boolean} Validation result
|
|
268
|
+
*/
|
|
269
|
+
validateSettings(settings) {
|
|
270
|
+
try {
|
|
271
|
+
// Check required properties
|
|
272
|
+
const required = ['language', 'sourceDir', 'sourceLanguage', 'defaultLanguages', 'outputDir'];
|
|
273
|
+
for (const prop of required) {
|
|
274
|
+
if (!(prop in settings)) {
|
|
275
|
+
console.error(`❌ Missing required setting: ${prop}`);
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Validate language codes
|
|
281
|
+
const validLanguages = ['en', 'de', 'es', 'fr', 'ru', 'ja', 'zh'];
|
|
282
|
+
if (!validLanguages.includes(settings.language)) {
|
|
283
|
+
console.error(`❌ Invalid language: ${settings.language}`);
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (!validLanguages.includes(settings.sourceLanguage)) {
|
|
288
|
+
console.error(`❌ Invalid source language: ${settings.sourceLanguage}`);
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Validate arrays
|
|
293
|
+
if (!Array.isArray(settings.defaultLanguages)) {
|
|
294
|
+
console.error('❌ defaultLanguages must be an array');
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Validate date format
|
|
299
|
+
const validDateFormats = ['DD/MM/YYYY', 'MM/DD/YYYY', 'YYYY-MM-DD', 'DD.MM.YYYY'];
|
|
300
|
+
if (settings.dateFormat && !validDateFormats.includes(settings.dateFormat)) {
|
|
301
|
+
console.error(`❌ Invalid dateFormat: ${settings.dateFormat}. Valid options: ${validDateFormats.join(', ')}`);
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Validate time format
|
|
306
|
+
const validTimeFormats = ['24h', '12h'];
|
|
307
|
+
if (settings.timeFormat && !validTimeFormats.includes(settings.timeFormat)) {
|
|
308
|
+
console.error(`❌ Invalid timeFormat: ${settings.timeFormat}. Valid options: ${validTimeFormats.join(', ')}`);
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Validate notifications settings
|
|
313
|
+
if (settings.notifications && typeof settings.notifications === 'object') {
|
|
314
|
+
if (settings.notifications.types && typeof settings.notifications.types !== 'object') {
|
|
315
|
+
console.error('❌ notifications.types must be an object');
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Validate processing settings
|
|
321
|
+
if (settings.processing && typeof settings.processing === 'object') {
|
|
322
|
+
const processing = settings.processing;
|
|
323
|
+
|
|
324
|
+
if (processing.excludeFiles && !Array.isArray(processing.excludeFiles)) {
|
|
325
|
+
console.error('❌ processing.excludeFiles must be an array');
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (processing.excludeDirs && !Array.isArray(processing.excludeDirs)) {
|
|
330
|
+
console.error('❌ processing.excludeDirs must be an array');
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (processing.includeExtensions && !Array.isArray(processing.includeExtensions)) {
|
|
335
|
+
console.error('❌ processing.includeExtensions must be an array');
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Validate advanced settings if present
|
|
341
|
+
if (settings.advanced) {
|
|
342
|
+
const advanced = settings.advanced;
|
|
343
|
+
|
|
344
|
+
if (advanced.batchSize && (typeof advanced.batchSize !== 'number' || advanced.batchSize < 1)) {
|
|
345
|
+
console.error('❌ Invalid batchSize: must be a positive number');
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (advanced.maxConcurrentFiles && (typeof advanced.maxConcurrentFiles !== 'number' || advanced.maxConcurrentFiles < 1)) {
|
|
350
|
+
console.error('❌ Invalid maxConcurrentFiles: must be a positive number');
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (advanced.sizingThreshold && (typeof advanced.sizingThreshold !== 'number' || advanced.sizingThreshold < 0)) {
|
|
355
|
+
console.error('❌ Invalid sizingThreshold: must be a non-negative number');
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (advanced.timeout && (typeof advanced.timeout !== 'number' || advanced.timeout < 1000)) {
|
|
360
|
+
console.error('❌ Invalid timeout: must be at least 1000ms');
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const validSizingFormats = ['table', 'json', 'csv'];
|
|
365
|
+
if (advanced.sizingFormat && !validSizingFormats.includes(advanced.sizingFormat)) {
|
|
366
|
+
console.error(`❌ Invalid sizingFormat: ${advanced.sizingFormat}. Valid options: ${validSizingFormats.join(', ')}`);
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return true;
|
|
372
|
+
} catch (error) {
|
|
373
|
+
console.error('❌ Error validating settings:', error.message);
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Create a backup of current settings
|
|
380
|
+
* @returns {boolean} Success status
|
|
381
|
+
*/
|
|
382
|
+
createBackup() {
|
|
383
|
+
try {
|
|
384
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
385
|
+
const backupDir = path.join(path.dirname(this.configFile), 'backups');
|
|
386
|
+
|
|
387
|
+
// Ensure backup directory exists
|
|
388
|
+
if (!fs.existsSync(backupDir)) {
|
|
389
|
+
fs.mkdirSync(backupDir, { recursive: true });
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const backupFile = path.join(backupDir, `${path.basename(this.configFile, '.json')}-backup-${timestamp}.json`);
|
|
393
|
+
|
|
394
|
+
if (fs.existsSync(this.configFile)) {
|
|
395
|
+
fs.copyFileSync(this.configFile, backupFile);
|
|
396
|
+
console.log(`📁 Settings backup created: ${path.relative(process.cwd(), backupFile)}`);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return true;
|
|
400
|
+
} catch (error) {
|
|
401
|
+
console.error('❌ Error creating backup:', error.message);
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Get available language options
|
|
408
|
+
* @returns {Array} Array of language objects
|
|
409
|
+
*/
|
|
410
|
+
getAvailableLanguages() {
|
|
411
|
+
return [
|
|
412
|
+
{ code: 'en', name: 'English', flag: '🇺🇸' },
|
|
413
|
+
{ code: 'de', name: 'Deutsch (German)', flag: '🇩🇪' },
|
|
414
|
+
{ code: 'es', name: 'Español (Spanish)', flag: '🇪���8' },
|
|
415
|
+
{ code: 'fr', name: 'Français (French)', flag: '🇫🇷' },
|
|
416
|
+
{ code: 'ru', name: 'Русский (Russian)', flag: '🇷🇺' },
|
|
417
|
+
{ code: 'ja', name: '日本語 (Japanese)', flag: '🇯🇵' },
|
|
418
|
+
{ code: 'zh', name: '中文 (Chinese)', flag: '🇨🇳' }
|
|
419
|
+
];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Set security settings
|
|
424
|
+
* @param {Object} securitySettings - Security settings object
|
|
425
|
+
*/
|
|
426
|
+
setSecurity(securitySettings) {
|
|
427
|
+
if (typeof securitySettings !== 'object' || securitySettings === null) {
|
|
428
|
+
throw new Error('Security settings must be an object');
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
this.settings.security = { ...this.settings.security, ...securitySettings };
|
|
432
|
+
this.saveSettings();
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Set debug settings
|
|
437
|
+
* @param {Object} debugSettings - Debug settings object
|
|
438
|
+
*/
|
|
439
|
+
setDebug(debugSettings) {
|
|
440
|
+
if (typeof debugSettings !== 'object' || debugSettings === null) {
|
|
441
|
+
throw new Error('Debug settings must be an object');
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
this.settings.debug = { ...this.settings.debug, ...debugSettings };
|
|
445
|
+
this.saveSettings();
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Get security settings
|
|
450
|
+
* @returns {Object} Security settings
|
|
451
|
+
*/
|
|
452
|
+
getSecurity() {
|
|
453
|
+
return this.settings.security || this.defaultConfig.security;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Get debug settings
|
|
458
|
+
* @returns {Object} Debug settings
|
|
459
|
+
*/
|
|
460
|
+
getDebug() {
|
|
461
|
+
return this.settings.debug || this.defaultConfig.debug;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Check if admin PIN is enabled
|
|
466
|
+
* @returns {boolean} True if admin PIN is enabled
|
|
467
|
+
*/
|
|
468
|
+
isAdminPinEnabled() {
|
|
469
|
+
return this.getSecurity().adminPinEnabled || false;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Check if debug mode is enabled
|
|
474
|
+
* @returns {boolean} True if debug mode is enabled
|
|
475
|
+
*/
|
|
476
|
+
isDebugEnabled() {
|
|
477
|
+
return this.getDebug().enabled || false;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Check if security logs should be shown
|
|
482
|
+
* @returns {boolean} True if security logs should be shown
|
|
483
|
+
*/
|
|
484
|
+
shouldShowSecurityLogs() {
|
|
485
|
+
const debug = this.getDebug();
|
|
486
|
+
return debug.enabled && debug.showSecurityLogs;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Get settings schema for UI generation
|
|
491
|
+
* @returns {object} Settings schema
|
|
492
|
+
*/
|
|
493
|
+
getSettingsSchema() {
|
|
494
|
+
return {
|
|
495
|
+
basic: {
|
|
496
|
+
title: 'Basic Settings',
|
|
497
|
+
fields: {
|
|
498
|
+
language: {
|
|
499
|
+
type: 'select',
|
|
500
|
+
label: 'UI Language',
|
|
501
|
+
options: this.getAvailableLanguages(),
|
|
502
|
+
description: 'Language for the user interface'
|
|
503
|
+
},
|
|
504
|
+
sourceDir: {
|
|
505
|
+
type: 'text',
|
|
506
|
+
label: 'Source Directory',
|
|
507
|
+
description: 'Directory containing translation files'
|
|
508
|
+
},
|
|
509
|
+
sourceLanguage: {
|
|
510
|
+
type: 'select',
|
|
511
|
+
label: 'Source Language',
|
|
512
|
+
options: this.getAvailableLanguages(),
|
|
513
|
+
description: 'Primary language for translations'
|
|
514
|
+
},
|
|
515
|
+
outputDir: {
|
|
516
|
+
type: 'text',
|
|
517
|
+
label: 'Output Directory',
|
|
518
|
+
description: 'Directory for generated reports'
|
|
519
|
+
},
|
|
520
|
+
theme: {
|
|
521
|
+
type: 'select',
|
|
522
|
+
label: 'Theme',
|
|
523
|
+
options: [
|
|
524
|
+
{ code: 'light', name: 'Light' },
|
|
525
|
+
{ code: 'dark', name: 'Dark' }
|
|
526
|
+
],
|
|
527
|
+
description: 'UI theme preference'
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
advanced: {
|
|
532
|
+
title: 'Advanced Settings',
|
|
533
|
+
fields: {
|
|
534
|
+
'advanced.batchSize': {
|
|
535
|
+
type: 'number',
|
|
536
|
+
label: 'Batch Size',
|
|
537
|
+
min: 1,
|
|
538
|
+
max: 1000,
|
|
539
|
+
description: 'Number of items processed per batch'
|
|
540
|
+
},
|
|
541
|
+
'advanced.maxConcurrentFiles': {
|
|
542
|
+
type: 'number',
|
|
543
|
+
label: 'Max Concurrent Files',
|
|
544
|
+
min: 1,
|
|
545
|
+
max: 50,
|
|
546
|
+
description: 'Maximum files processed simultaneously'
|
|
547
|
+
},
|
|
548
|
+
'advanced.sizingThreshold': {
|
|
549
|
+
type: 'number',
|
|
550
|
+
label: 'Sizing Threshold (%)',
|
|
551
|
+
min: 0,
|
|
552
|
+
max: 200,
|
|
553
|
+
description: 'Threshold for size variation warnings'
|
|
554
|
+
},
|
|
555
|
+
'advanced.strictMode': {
|
|
556
|
+
type: 'checkbox',
|
|
557
|
+
label: 'Strict Mode',
|
|
558
|
+
description: 'Enable strict validation mode'
|
|
559
|
+
},
|
|
560
|
+
'advanced.enableAuditLog': {
|
|
561
|
+
type: 'checkbox',
|
|
562
|
+
label: 'Enable Audit Log',
|
|
563
|
+
description: 'Track all translation changes'
|
|
564
|
+
},
|
|
565
|
+
'advanced.backupBeforeChanges': {
|
|
566
|
+
type: 'checkbox',
|
|
567
|
+
label: 'Backup Before Changes',
|
|
568
|
+
description: 'Create backups before modifications'
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Set UI language
|
|
577
|
+
* @param {string} language - Language code (e.g., 'en', 'de', 'fr')
|
|
578
|
+
*/
|
|
579
|
+
setLanguage(language) {
|
|
580
|
+
if (typeof language !== 'string' || language.length === 0) {
|
|
581
|
+
throw new Error('Language must be a non-empty string');
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
const availableLanguages = this.getAvailableLanguages().map(lang => lang.code);
|
|
585
|
+
if (!availableLanguages.includes(language)) {
|
|
586
|
+
throw new Error(`Language '${language}' is not supported. Available: ${availableLanguages.join(', ')}`);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
this.settings.language = language;
|
|
590
|
+
this.saveSettings();
|
|
591
|
+
console.log(`🌍 UI language set to: ${language}`);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// Export singleton instance
|
|
596
|
+
module.exports = new SettingsManager();
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"language": "zh",
|
|
3
|
+
"sizeLimit": null,
|
|
4
|
+
"sourceDir": "./locales",
|
|
5
|
+
"sourceLanguage": "en",
|
|
6
|
+
"defaultLanguages": [
|
|
7
|
+
"de",
|
|
8
|
+
"es",
|
|
9
|
+
"fr",
|
|
10
|
+
"ru"
|
|
11
|
+
],
|
|
12
|
+
"outputDir": "./i18ntk-reports",
|
|
13
|
+
"reportLanguage": "auto",
|
|
14
|
+
"theme": "light",
|
|
15
|
+
"autoSave": true,
|
|
16
|
+
"notifications": {
|
|
17
|
+
"enabled": true,
|
|
18
|
+
"types": {
|
|
19
|
+
"success": true,
|
|
20
|
+
"warnings": true,
|
|
21
|
+
"errors": true,
|
|
22
|
+
"progress": true
|
|
23
|
+
},
|
|
24
|
+
"sound": false,
|
|
25
|
+
"desktop": false
|
|
26
|
+
},
|
|
27
|
+
"dateFormat": "DD/MM/YYYY",
|
|
28
|
+
"timeFormat": "24h",
|
|
29
|
+
"timezone": "auto",
|
|
30
|
+
"processing": {
|
|
31
|
+
"notTranslatedMarker": "NOT_TRANSLATED",
|
|
32
|
+
"excludeFiles": [
|
|
33
|
+
".DS_Store",
|
|
34
|
+
"Thumbs.db",
|
|
35
|
+
"*.tmp"
|
|
36
|
+
],
|
|
37
|
+
"excludeDirs": [
|
|
38
|
+
"node_modules",
|
|
39
|
+
".git",
|
|
40
|
+
"dist",
|
|
41
|
+
"build"
|
|
42
|
+
],
|
|
43
|
+
"includeExtensions": [
|
|
44
|
+
".js",
|
|
45
|
+
".jsx",
|
|
46
|
+
".ts",
|
|
47
|
+
".tsx",
|
|
48
|
+
".vue",
|
|
49
|
+
".svelte"
|
|
50
|
+
],
|
|
51
|
+
"strictMode": false,
|
|
52
|
+
"defaultLanguages": [
|
|
53
|
+
"de",
|
|
54
|
+
"es",
|
|
55
|
+
"fr",
|
|
56
|
+
"ru"
|
|
57
|
+
],
|
|
58
|
+
"translationPatterns": [
|
|
59
|
+
{},
|
|
60
|
+
{},
|
|
61
|
+
{}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"advanced": {
|
|
65
|
+
"batchSize": 100,
|
|
66
|
+
"maxConcurrentFiles": 10,
|
|
67
|
+
"enableProgressBars": true,
|
|
68
|
+
"enableColorOutput": true,
|
|
69
|
+
"strictMode": false,
|
|
70
|
+
"enableAuditLog": false,
|
|
71
|
+
"backupBeforeChanges": true,
|
|
72
|
+
"validateOnSave": true,
|
|
73
|
+
"sizingThreshold": 50,
|
|
74
|
+
"sizingFormat": "table",
|
|
75
|
+
"memoryLimit": "512MB",
|
|
76
|
+
"timeout": 30000
|
|
77
|
+
},
|
|
78
|
+
"security": {
|
|
79
|
+
"adminPinEnabled": "1111",
|
|
80
|
+
"adminPinPromptOnInit": false,
|
|
81
|
+
"keepAuthenticatedUntilExit": true,
|
|
82
|
+
"sessionTimeout": 30,
|
|
83
|
+
"maxFailedAttempts": 3,
|
|
84
|
+
"lockoutDuration": 15
|
|
85
|
+
},
|
|
86
|
+
"debug": {
|
|
87
|
+
"enabled": false,
|
|
88
|
+
"showSecurityLogs": false,
|
|
89
|
+
"verboseLogging": false,
|
|
90
|
+
"logLevel": "info",
|
|
91
|
+
"saveDebugLogs": false,
|
|
92
|
+
"debugLogPath": "./debug.log"
|
|
93
|
+
},
|
|
94
|
+
"ui": {
|
|
95
|
+
"language": "fr"
|
|
96
|
+
}
|
|
97
|
+
}
|