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.
- package/CHANGELOG.md +401 -0
- package/LICENSE +21 -0
- package/README.md +507 -0
- package/dev/README.md +37 -0
- package/dev/debug/README.md +30 -0
- package/dev/debug/complete-console-translations.js +295 -0
- package/dev/debug/console-key-checker.js +408 -0
- package/dev/debug/console-translations.js +335 -0
- package/dev/debug/debugger.js +408 -0
- package/dev/debug/export-missing-keys.js +432 -0
- package/dev/debug/final-normalize.js +236 -0
- package/dev/debug/find-extra-keys.js +68 -0
- package/dev/debug/normalize-locales.js +153 -0
- package/dev/debug/refactor-locales.js +240 -0
- package/dev/debug/reorder-locales.js +85 -0
- package/dev/debug/replace-hardcoded-console.js +378 -0
- package/docs/INSTALLATION.md +449 -0
- package/docs/README.md +222 -0
- package/docs/TODO_ROADMAP.md +279 -0
- package/docs/api/API_REFERENCE.md +377 -0
- package/docs/api/COMPONENTS.md +492 -0
- package/docs/api/CONFIGURATION.md +651 -0
- package/docs/api/NPM_PUBLISHING_GUIDE.md +434 -0
- package/docs/debug/DEBUG_README.md +30 -0
- package/docs/debug/DEBUG_TOOLS.md +494 -0
- package/docs/development/AGENTS.md +351 -0
- package/docs/development/DEVELOPMENT_RULES.md +165 -0
- package/docs/development/DEV_README.md +37 -0
- package/docs/release-notes/RELEASE_NOTES_v1.0.0.md +173 -0
- package/docs/release-notes/RELEASE_NOTES_v1.6.0.md +141 -0
- package/docs/release-notes/RELEASE_NOTES_v1.6.1.md +185 -0
- package/docs/release-notes/RELEASE_NOTES_v1.6.3.md +199 -0
- package/docs/reports/ANALYSIS_README.md +17 -0
- package/docs/reports/CONSOLE_MISMATCH_BUG_REPORT_v1.5.0.md +181 -0
- package/docs/reports/SIZING_README.md +18 -0
- package/docs/reports/SUMMARY_README.md +18 -0
- package/docs/reports/TRANSLATION_BUG_REPORT_v1.5.0.md +129 -0
- package/docs/reports/USAGE_README.md +18 -0
- package/docs/reports/VALIDATION_README.md +18 -0
- package/locales/de/auth.json +3 -0
- package/locales/de/common.json +16 -0
- package/locales/de/pagination.json +6 -0
- package/locales/en/auth.json +3 -0
- package/locales/en/common.json +16 -0
- package/locales/en/pagination.json +6 -0
- package/locales/es/auth.json +3 -0
- package/locales/es/common.json +16 -0
- package/locales/es/pagination.json +6 -0
- package/locales/fr/auth.json +3 -0
- package/locales/fr/common.json +16 -0
- package/locales/fr/pagination.json +6 -0
- package/locales/ru/auth.json +3 -0
- package/locales/ru/common.json +16 -0
- package/locales/ru/pagination.json +6 -0
- package/main/i18ntk-analyze.js +625 -0
- package/main/i18ntk-autorun.js +461 -0
- package/main/i18ntk-complete.js +494 -0
- package/main/i18ntk-init.js +686 -0
- package/main/i18ntk-manage.js +848 -0
- package/main/i18ntk-sizing.js +557 -0
- package/main/i18ntk-summary.js +671 -0
- package/main/i18ntk-usage.js +1282 -0
- package/main/i18ntk-validate.js +762 -0
- package/main/ui-i18n.js +332 -0
- package/package.json +152 -0
- package/scripts/fix-missing-translation-keys.js +214 -0
- package/scripts/verify-package.js +168 -0
- package/ui-locales/de.json +637 -0
- package/ui-locales/en.json +688 -0
- package/ui-locales/es.json +637 -0
- package/ui-locales/fr.json +637 -0
- package/ui-locales/ja.json +637 -0
- package/ui-locales/ru.json +637 -0
- package/ui-locales/zh.json +637 -0
- package/utils/admin-auth.js +317 -0
- package/utils/admin-cli.js +353 -0
- package/utils/admin-pin.js +409 -0
- package/utils/detect-language-mismatches.js +454 -0
- package/utils/i18n-helper.js +128 -0
- package/utils/maintain-language-purity.js +433 -0
- package/utils/native-translations.js +478 -0
- package/utils/security.js +384 -0
- package/utils/test-complete-system.js +356 -0
- package/utils/test-console-i18n.js +402 -0
- package/utils/translate-mismatches.js +571 -0
- package/utils/validate-language-purity.js +531 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* i18nTK Debugger
|
|
5
|
+
* Main debugging script for identifying and fixing issues in the i18n toolkit
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { execSync } = require('child_process');
|
|
11
|
+
const SecurityUtils = require('../../utils/security');
|
|
12
|
+
|
|
13
|
+
class I18nDebugger {
|
|
14
|
+
constructor(projectRoot = null) {
|
|
15
|
+
// Validate and sanitize project root path
|
|
16
|
+
const defaultRoot = path.resolve(__dirname, '../..');
|
|
17
|
+
const validatedRoot = SecurityUtils.validatePath(projectRoot || defaultRoot, process.cwd());
|
|
18
|
+
if (!validatedRoot) {
|
|
19
|
+
throw new Error('Invalid project root path provided');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
this.projectRoot = validatedRoot;
|
|
23
|
+
this.issues = [];
|
|
24
|
+
this.warnings = [];
|
|
25
|
+
this.logFile = path.join(__dirname, 'logs', `debug-${new Date().toISOString().replace(/[:.]/g, '-')}.log`);
|
|
26
|
+
|
|
27
|
+
// Ensure logs directory exists
|
|
28
|
+
const logsDir = path.dirname(this.logFile);
|
|
29
|
+
if (!fs.existsSync(logsDir)) {
|
|
30
|
+
fs.mkdirSync(logsDir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
log(message, level = 'INFO') {
|
|
35
|
+
const timestamp = new Date().toISOString();
|
|
36
|
+
const logMessage = `[${timestamp}] [${level}] ${message}`;
|
|
37
|
+
console.log(logMessage);
|
|
38
|
+
fs.appendFileSync(this.logFile, logMessage + '\n');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
addIssue(issue) {
|
|
42
|
+
this.issues.push(issue);
|
|
43
|
+
this.log(`ISSUE: ${issue}`, 'ERROR');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
addWarning(warning) {
|
|
47
|
+
this.warnings.push(warning);
|
|
48
|
+
this.log(`WARNING: ${warning}`, 'WARN');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
checkFileExists(filePath, description) {
|
|
52
|
+
try {
|
|
53
|
+
// Validate path before checking existence
|
|
54
|
+
const validatedPath = SecurityUtils.validatePath(filePath, this.projectRoot);
|
|
55
|
+
if (!validatedPath) {
|
|
56
|
+
this.addIssue(`Invalid file path: ${filePath}`);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const fullPath = path.resolve(this.projectRoot, filePath);
|
|
61
|
+
if (!fs.existsSync(fullPath)) {
|
|
62
|
+
this.addIssue(`Missing file: ${filePath} (${description})`);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
this.log(`â Found: ${filePath}`);
|
|
66
|
+
return true;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
this.addIssue(`Error checking file existence: ${filePath} - ${error.message}`);
|
|
69
|
+
SecurityUtils.logSecurityEvent('File existence check failed', 'warn', { filePath, error: error.message });
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
checkOldNamingConventions() {
|
|
75
|
+
this.log('Checking for old naming conventions...');
|
|
76
|
+
const oldFiles = [
|
|
77
|
+
'00-manage-i18n.js',
|
|
78
|
+
'01-init-i18n.js',
|
|
79
|
+
'02-analyze-translations.js',
|
|
80
|
+
'03-validate-translations.js',
|
|
81
|
+
'04-check-usage.js',
|
|
82
|
+
'05-complete-translations.js',
|
|
83
|
+
'06-analyze-sizing.js',
|
|
84
|
+
'07-generate-summary.js'
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
oldFiles.forEach(file => {
|
|
88
|
+
const fullPath = path.resolve(this.projectRoot, file);
|
|
89
|
+
if (fs.existsSync(fullPath)) {
|
|
90
|
+
this.addIssue(`Old naming convention file still exists: ${file}`);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Check for references to old files in code
|
|
95
|
+
this.checkForOldReferences();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async checkForOldReferences() {
|
|
99
|
+
this.log('Checking for old file references in code...');
|
|
100
|
+
const filesToCheck = [
|
|
101
|
+
'i18ntk-complete.js',
|
|
102
|
+
'i18ntk-usage.js',
|
|
103
|
+
'i18ntk-validate.js',
|
|
104
|
+
'package.json'
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
const oldReferences = [
|
|
108
|
+
'04-check-usage.js',
|
|
109
|
+
'00-manage-i18n.js',
|
|
110
|
+
'01-init-i18n.js',
|
|
111
|
+
'02-analyze-translations.js',
|
|
112
|
+
'03-validate-translations.js',
|
|
113
|
+
'05-complete-translations.js',
|
|
114
|
+
'06-analyze-sizing.js',
|
|
115
|
+
'07-generate-summary.js'
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
for (const file of filesToCheck) {
|
|
119
|
+
const fullPath = path.resolve(this.projectRoot, file);
|
|
120
|
+
if (fs.existsSync(fullPath)) {
|
|
121
|
+
try {
|
|
122
|
+
const content = await SecurityUtils.safeReadFile(fullPath, this.projectRoot);
|
|
123
|
+
if (content) {
|
|
124
|
+
oldReferences.forEach(oldRef => {
|
|
125
|
+
if (content.includes(oldRef)) {
|
|
126
|
+
this.addIssue(`Old reference '${oldRef}' found in ${file}`);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
} catch (error) {
|
|
131
|
+
this.addIssue(`Error reading file ${fullPath}: ${error.message}`);
|
|
132
|
+
SecurityUtils.logSecurityEvent('File read failed during reference check', 'error', { filePath: fullPath, error: error.message });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async checkTranslationKeys() {
|
|
139
|
+
this.log('Checking for missing translation keys...');
|
|
140
|
+
const uiLocalesDir = path.resolve(this.projectRoot, 'ui-locales');
|
|
141
|
+
|
|
142
|
+
if (!fs.existsSync(uiLocalesDir)) {
|
|
143
|
+
this.addIssue('ui-locales directory not found');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const localeFiles = fs.readdirSync(uiLocalesDir).filter(f => f.endsWith('.json'));
|
|
148
|
+
if (localeFiles.length === 0) {
|
|
149
|
+
this.addIssue('No locale files found in ui-locales directory');
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Load English as reference
|
|
154
|
+
const enPath = path.join(uiLocalesDir, 'en.json');
|
|
155
|
+
if (!fs.existsSync(enPath)) {
|
|
156
|
+
this.addIssue('English locale file (en.json) not found');
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
const enContent = await SecurityUtils.safeReadFile(enPath, this.projectRoot);
|
|
162
|
+
if (!enContent) {
|
|
163
|
+
this.addIssue('Failed to read en.json file');
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const enLocale = SecurityUtils.safeParseJSON(enContent);
|
|
168
|
+
if (!enLocale) {
|
|
169
|
+
this.addIssue('Failed to parse en.json file');
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const requiredKeys = this.extractAllKeys(enLocale);
|
|
174
|
+
|
|
175
|
+
for (const file of localeFiles) {
|
|
176
|
+
const filePath = path.join(uiLocalesDir, file);
|
|
177
|
+
try {
|
|
178
|
+
const content = await SecurityUtils.safeReadFile(filePath, this.projectRoot);
|
|
179
|
+
if (!content) {
|
|
180
|
+
this.addIssue(`Failed to read ${file}`);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const locale = SecurityUtils.safeParseJSON(content);
|
|
185
|
+
if (!locale) {
|
|
186
|
+
this.addIssue(`Failed to parse ${file}`);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const existingKeys = this.extractAllKeys(locale);
|
|
191
|
+
|
|
192
|
+
const missingKeys = requiredKeys.filter(key => !existingKeys.includes(key));
|
|
193
|
+
if (missingKeys.length > 0) {
|
|
194
|
+
this.addIssue(`Missing translation keys in ${file}: ${missingKeys.join(', ')}`);
|
|
195
|
+
}
|
|
196
|
+
} catch (error) {
|
|
197
|
+
this.addIssue(`Error processing ${file}: ${error.message}`);
|
|
198
|
+
SecurityUtils.logSecurityEvent('Translation file processing failed', 'error', { file, error: error.message });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
} catch (error) {
|
|
202
|
+
this.addIssue(`Error processing en.json: ${error.message}`);
|
|
203
|
+
SecurityUtils.logSecurityEvent('English translation file processing failed', 'error', { error: error.message });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
extractAllKeys(obj, prefix = '') {
|
|
208
|
+
let keys = [];
|
|
209
|
+
for (const key in obj) {
|
|
210
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
211
|
+
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
|
|
212
|
+
keys = keys.concat(this.extractAllKeys(obj[key], fullKey));
|
|
213
|
+
} else {
|
|
214
|
+
keys.push(fullKey);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return keys;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async checkUserConfig() {
|
|
221
|
+
this.log('Checking user configuration...');
|
|
222
|
+
|
|
223
|
+
// Check user-config.json
|
|
224
|
+
const configPath = path.resolve(this.projectRoot, 'user-config.json');
|
|
225
|
+
if (this.checkFileExists('user-config.json', 'Main configuration file')) {
|
|
226
|
+
try {
|
|
227
|
+
const content = await SecurityUtils.safeReadFile(configPath, this.projectRoot);
|
|
228
|
+
if (!content) {
|
|
229
|
+
this.addIssue('Failed to read user-config.json');
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const config = SecurityUtils.safeParseJSON(content);
|
|
234
|
+
if (!config) {
|
|
235
|
+
this.addIssue('Failed to parse user-config.json');
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Validate configuration structure
|
|
240
|
+
const validatedConfig = SecurityUtils.validateConfig(config);
|
|
241
|
+
if (!validatedConfig) {
|
|
242
|
+
this.addIssue('Invalid configuration structure in user-config.json');
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Check required sections
|
|
247
|
+
const requiredSections = ['directories', 'processing', 'advanced', 'ui'];
|
|
248
|
+
requiredSections.forEach(section => {
|
|
249
|
+
if (!validatedConfig[section]) {
|
|
250
|
+
this.addWarning(`Missing configuration section: ${section}`);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// Check directory paths with security validation
|
|
255
|
+
if (validatedConfig.directories) {
|
|
256
|
+
const dirs = ['sourceDir', 'outputDir', 'uiLocalesDir'];
|
|
257
|
+
dirs.forEach(dir => {
|
|
258
|
+
if (validatedConfig.directories[dir]) {
|
|
259
|
+
const dirPath = SecurityUtils.validatePath(validatedConfig.directories[dir], this.projectRoot);
|
|
260
|
+
if (!dirPath || !fs.existsSync(dirPath)) {
|
|
261
|
+
this.addWarning(`Configured directory does not exist or is invalid: ${validatedConfig.directories[dir]}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
} catch (error) {
|
|
267
|
+
this.addIssue(`Error processing user-config.json: ${error.message}`);
|
|
268
|
+
SecurityUtils.logSecurityEvent('User config processing failed', 'error', { error: error.message });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
checkPackageJson() {
|
|
274
|
+
this.log('Checking package configuration...');
|
|
275
|
+
this.checkFileExists('package.json', 'Package configuration');
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
checkCoreFiles() {
|
|
279
|
+
this.log('Checking core i18nTK files...');
|
|
280
|
+
const coreFiles = [
|
|
281
|
+
'i18ntk-manage.js',
|
|
282
|
+
'i18ntk-init.js',
|
|
283
|
+
'i18ntk-analyze.js',
|
|
284
|
+
'i18ntk-validate.js',
|
|
285
|
+
'i18ntk-usage.js',
|
|
286
|
+
'i18ntk-complete.js',
|
|
287
|
+
'i18ntk-sizing.js',
|
|
288
|
+
'i18ntk-summary.js'
|
|
289
|
+
];
|
|
290
|
+
|
|
291
|
+
coreFiles.forEach(file => {
|
|
292
|
+
this.checkFileExists(file, 'Core i18nTK script');
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
checkDependencies() {
|
|
297
|
+
this.log('Checking dependencies...');
|
|
298
|
+
try {
|
|
299
|
+
const packageJson = JSON.parse(fs.readFileSync(path.resolve(this.projectRoot, 'package.json'), 'utf8'));
|
|
300
|
+
const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
301
|
+
|
|
302
|
+
// Check if node_modules exists
|
|
303
|
+
const nodeModulesPath = path.resolve(this.projectRoot, 'node_modules');
|
|
304
|
+
if (!fs.existsSync(nodeModulesPath)) {
|
|
305
|
+
this.addWarning('node_modules directory not found. Run npm install.');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
this.log(`Found ${Object.keys(dependencies).length} dependencies`);
|
|
309
|
+
} catch (error) {
|
|
310
|
+
this.addIssue(`Could not check dependencies: ${error.message}`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
async generateReport() {
|
|
315
|
+
const timestamp = new Date().toLocaleString();
|
|
316
|
+
let summary = '';
|
|
317
|
+
|
|
318
|
+
summary += '\n' + '='.repeat(60) + '\n';
|
|
319
|
+
summary += ' i18nTK DEBUG REPORT\n';
|
|
320
|
+
summary += '='.repeat(60) + '\n';
|
|
321
|
+
summary += `Generated: ${timestamp}\n`;
|
|
322
|
+
summary += `Project Root: ${this.projectRoot}\n`;
|
|
323
|
+
summary += '-'.repeat(60) + '\n';
|
|
324
|
+
summary += `đ Summary: ${this.issues.length} issue(s), ${this.warnings.length} warning(s)\n`;
|
|
325
|
+
summary += '-'.repeat(60) + '\n';
|
|
326
|
+
|
|
327
|
+
if (this.issues.length > 0) {
|
|
328
|
+
summary += '\nđ¨ CRITICAL ISSUES:\n';
|
|
329
|
+
this.issues.forEach((issue, index) => {
|
|
330
|
+
summary += ` ${index + 1}. â ${issue}\n`;
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (this.warnings.length > 0) {
|
|
335
|
+
summary += '\nâ ď¸ WARNINGS:\n';
|
|
336
|
+
this.warnings.forEach((warning, index) => {
|
|
337
|
+
summary += ` ${index + 1}. â ď¸ ${warning}\n`;
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (this.issues.length === 0 && this.warnings.length === 0) {
|
|
342
|
+
summary += '\nâ
EXCELLENT! No issues found.\n';
|
|
343
|
+
summary += ' The i18nTK project appears to be healthy.\n';
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
summary += '\n' + '='.repeat(60) + '\n';
|
|
347
|
+
summary += `đ Full debug log: ${this.logFile}\n`;
|
|
348
|
+
summary += '='.repeat(60) + '\n';
|
|
349
|
+
|
|
350
|
+
console.log(summary);
|
|
351
|
+
|
|
352
|
+
// Save report to file securely
|
|
353
|
+
const reportPath = path.join(path.dirname(this.logFile), 'debug-report.txt');
|
|
354
|
+
const success = await SecurityUtils.safeWriteFile(reportPath, summary, this.projectRoot);
|
|
355
|
+
if (!success) {
|
|
356
|
+
console.warn('Warning: Could not save debug report due to security restrictions');
|
|
357
|
+
SecurityUtils.logSecurityEvent('Debug report save failed', 'warn', { reportPath });
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return {
|
|
361
|
+
issues: this.issues,
|
|
362
|
+
warnings: this.warnings,
|
|
363
|
+
summary: summary,
|
|
364
|
+
reportPath: reportPath,
|
|
365
|
+
logFile: this.logFile
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
async run() {
|
|
370
|
+
this.log('Starting i18nTK Debug Analysis...');
|
|
371
|
+
this.log(`Project Root: ${this.projectRoot}`);
|
|
372
|
+
|
|
373
|
+
SecurityUtils.logSecurityEvent('Debug analysis started', 'info', { projectRoot: this.projectRoot });
|
|
374
|
+
|
|
375
|
+
try {
|
|
376
|
+
this.checkCoreFiles();
|
|
377
|
+
await this.checkUserConfig();
|
|
378
|
+
this.checkPackageJson();
|
|
379
|
+
this.checkOldNamingConventions();
|
|
380
|
+
await this.checkTranslationKeys();
|
|
381
|
+
this.checkDependencies();
|
|
382
|
+
|
|
383
|
+
SecurityUtils.logSecurityEvent('Debug analysis completed', 'info', {
|
|
384
|
+
issuesFound: this.issues.length,
|
|
385
|
+
warningsFound: this.warnings.length
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
return await this.generateReport();
|
|
389
|
+
} catch (error) {
|
|
390
|
+
this.addIssue(`Debug analysis failed: ${error.message}`);
|
|
391
|
+
SecurityUtils.logSecurityEvent('Debug analysis failed', 'error', { error: error.message });
|
|
392
|
+
return await this.generateReport();
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Run debugger if called directly
|
|
398
|
+
if (require.main === module) {
|
|
399
|
+
const debugTool = new I18nDebugger();
|
|
400
|
+
debugTool.run().then(result => {
|
|
401
|
+
process.exit(result.issues.length > 0 ? 1 : 0);
|
|
402
|
+
}).catch(error => {
|
|
403
|
+
console.error('Debugger failed:', error);
|
|
404
|
+
process.exit(1);
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
module.exports = I18nDebugger;
|