i18ntk 1.10.2 ā 2.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/LICENSE +1 -1
- package/README.md +141 -1191
- package/main/i18ntk-analyze.js +65 -84
- package/main/i18ntk-backup-class.js +420 -0
- package/main/i18ntk-backup.js +3 -3
- package/main/i18ntk-complete.js +90 -65
- package/main/i18ntk-doctor.js +123 -103
- package/main/i18ntk-fixer.js +61 -725
- package/main/i18ntk-go.js +14 -15
- package/main/i18ntk-init.js +77 -26
- package/main/i18ntk-java.js +27 -32
- package/main/i18ntk-js.js +70 -68
- package/main/i18ntk-manage.js +129 -30
- package/main/i18ntk-php.js +75 -75
- package/main/i18ntk-py.js +55 -56
- package/main/i18ntk-scanner.js +59 -57
- package/main/i18ntk-setup.js +9 -404
- package/main/i18ntk-sizing.js +6 -6
- package/main/i18ntk-summary.js +21 -18
- package/main/i18ntk-ui.js +11 -10
- package/main/i18ntk-usage.js +54 -18
- package/main/i18ntk-validate.js +13 -13
- package/main/manage/commands/AnalyzeCommand.js +1124 -0
- package/main/manage/commands/BackupCommand.js +62 -0
- package/main/manage/commands/CommandRouter.js +295 -0
- package/main/manage/commands/CompleteCommand.js +61 -0
- package/main/manage/commands/DoctorCommand.js +60 -0
- package/main/manage/commands/FixerCommand.js +624 -0
- package/main/manage/commands/InitCommand.js +62 -0
- package/main/manage/commands/ScannerCommand.js +654 -0
- package/main/manage/commands/SizingCommand.js +60 -0
- package/main/manage/commands/SummaryCommand.js +61 -0
- package/main/manage/commands/UsageCommand.js +60 -0
- package/main/manage/commands/ValidateCommand.js +978 -0
- package/main/manage/index-fixed.js +1447 -0
- package/main/manage/index.js +1462 -0
- package/main/manage/managers/DebugMenu.js +140 -0
- package/main/manage/managers/InteractiveMenu.js +177 -0
- package/main/manage/managers/LanguageMenu.js +62 -0
- package/main/manage/managers/SettingsMenu.js +53 -0
- package/main/manage/services/AuthenticationService.js +263 -0
- package/main/manage/services/ConfigurationService-fixed.js +449 -0
- package/main/manage/services/ConfigurationService.js +449 -0
- package/main/manage/services/FileManagementService.js +368 -0
- package/main/manage/services/FrameworkDetectionService.js +458 -0
- package/main/manage/services/InitService.js +1051 -0
- package/main/manage/services/SetupService.js +462 -0
- package/main/manage/services/SummaryService.js +450 -0
- package/main/manage/services/UsageService.js +1502 -0
- package/package.json +32 -29
- package/runtime/enhanced.d.ts +221 -221
- package/runtime/index.d.ts +29 -29
- package/runtime/index.full.d.ts +331 -331
- package/runtime/index.js +7 -6
- package/scripts/build-lite.js +17 -17
- package/scripts/deprecate-versions.js +23 -6
- package/scripts/export-translations.js +5 -5
- package/scripts/fix-all-i18n.js +3 -3
- package/scripts/fix-and-purify-i18n.js +3 -2
- package/scripts/fix-locale-control-chars.js +110 -0
- package/scripts/lint-locales.js +80 -0
- package/scripts/locale-optimizer.js +8 -8
- package/scripts/prepublish.js +21 -21
- package/scripts/security-check.js +117 -117
- package/scripts/sync-translations.js +4 -4
- package/scripts/sync-ui-locales.js +9 -8
- package/scripts/validate-all-translations.js +8 -7
- package/scripts/verify-deprecations.js +157 -161
- package/scripts/verify-translations.js +6 -5
- package/settings/i18ntk-config.json +282 -282
- package/settings/language-config.json +5 -5
- package/settings/settings-cli.js +9 -9
- package/settings/settings-manager.js +18 -18
- package/ui-locales/de.json +2417 -2348
- package/ui-locales/en.json +2415 -2352
- package/ui-locales/es.json +2425 -2353
- package/ui-locales/fr.json +2418 -2348
- package/ui-locales/ja.json +2463 -2361
- package/ui-locales/ru.json +2463 -2359
- package/ui-locales/zh.json +2418 -2351
- package/utils/admin-auth.js +2 -2
- package/utils/admin-cli.js +297 -297
- package/utils/admin-pin.js +9 -9
- package/utils/cli-helper.js +9 -9
- package/utils/config-helper.js +73 -104
- package/utils/config-manager.js +204 -171
- package/utils/config.js +5 -4
- package/utils/env-manager.js +249 -263
- package/utils/framework-detector.js +27 -24
- package/utils/i18n-helper.js +85 -41
- package/utils/init-helper.js +152 -94
- package/utils/json-output.js +98 -98
- package/utils/mini-commander.js +179 -0
- package/utils/missing-key-validator.js +5 -5
- package/utils/plugin-loader.js +40 -29
- package/utils/prompt.js +14 -44
- package/utils/safe-json.js +40 -0
- package/utils/secure-errors.js +3 -3
- package/utils/security-check-improved.js +390 -0
- package/utils/security-config.js +5 -5
- package/utils/security-fixed.js +607 -0
- package/utils/security.js +652 -602
- package/utils/setup-enforcer.js +136 -44
- package/utils/setup-validator.js +33 -32
- package/utils/ultra-performance-optimizer.js +11 -9
- package/utils/watch-locales.js +2 -1
- package/utils/prompt-fixed.js +0 -55
- package/utils/security-check.js +0 -454
package/main/i18ntk-manage.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* I18NTK MANAGEMENT TOOLKIT - MAIN MANAGER
|
|
4
4
|
*
|
|
@@ -18,11 +18,12 @@
|
|
|
18
18
|
* node i18ntk-manage.js --command=init
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
const fs = require('fs');
|
|
22
21
|
const path = require('path');
|
|
23
22
|
const UIi18n = require('./i18ntk-ui');
|
|
24
23
|
const AdminAuth = require('../utils/admin-auth');
|
|
25
24
|
const SecurityUtils = require('../utils/security');
|
|
25
|
+
|
|
26
|
+
|
|
26
27
|
const AdminCLI = require('../utils/admin-cli');
|
|
27
28
|
const configManager = require('../settings/settings-manager');
|
|
28
29
|
const { showFrameworkWarningOnce } = require('../utils/cli-helper');
|
|
@@ -36,6 +37,8 @@ const SettingsCLI = require('../settings/settings-cli');
|
|
|
36
37
|
// const I18nDebugger = require('../scripts/debug/debugger');
|
|
37
38
|
const { createPrompt, isInteractive } = require('../utils/prompt-helper');
|
|
38
39
|
const { loadTranslations, t, refreshLanguageFromSettings} = require('../utils/i18n-helper');
|
|
40
|
+
// Preload translations early to avoid missing key warnings
|
|
41
|
+
loadTranslations();
|
|
39
42
|
const cliHelper = require('../utils/cli-helper');
|
|
40
43
|
const { loadConfig, saveConfig, ensureConfigDefaults } = require('../utils/config');
|
|
41
44
|
const pkg = require('../package.json');
|
|
@@ -50,10 +53,6 @@ async function runInitFlow() {
|
|
|
50
53
|
return { i18nDir: settings.i18nDir, sourceDir: settings.sourceDir };
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
56
|
/**
|
|
58
57
|
* Ensures the project is properly initialized or exits the process
|
|
59
58
|
* @param {Object} prompt - Prompt interface for user interaction
|
|
@@ -129,7 +128,7 @@ async function ensureInitializedOrExit(prompt) {
|
|
|
129
128
|
console.log('Framework detection prompt will be suppressed for this version.');
|
|
130
129
|
} else if (action === 'detect') {
|
|
131
130
|
// Run framework detection
|
|
132
|
-
const { detectedLanguage, detectedFramework } = detectEnvironmentAndFramework();
|
|
131
|
+
const { detectedLanguage, detectedFramework } = await detectEnvironmentAndFramework();
|
|
133
132
|
|
|
134
133
|
if (detectedFramework && detectedFramework !== 'generic') {
|
|
135
134
|
console.log(`\nDetected framework: ${detectedFramework}`);
|
|
@@ -156,7 +155,90 @@ async function ensureInitializedOrExit(prompt) {
|
|
|
156
155
|
return { ...config, ...settings };
|
|
157
156
|
}
|
|
158
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Custom glob implementation using Node.js built-in modules (zero dependencies)
|
|
160
|
+
* @param {string[]} patterns - Array of glob patterns
|
|
161
|
+
* @param {Object} options - Options object with cwd and ignore properties
|
|
162
|
+
* @returns {Promise<string[]>} Array of matching file paths
|
|
163
|
+
*/
|
|
164
|
+
async function customGlob(patterns, options = {}) {
|
|
165
|
+
const fs = require('fs');
|
|
166
|
+
const path = require('path');
|
|
167
|
+
const cwd = options.cwd || process.cwd();
|
|
168
|
+
const ignorePatterns = options.ignore || [];
|
|
169
|
+
|
|
170
|
+
function matchesPattern(filename, pattern) {
|
|
171
|
+
// Simple pattern matching for **/*.{js,jsx,ts,tsx} style patterns
|
|
172
|
+
if (pattern.includes('**/*')) {
|
|
173
|
+
const extensionPart = pattern.split('*.')[1];
|
|
174
|
+
if (extensionPart) {
|
|
175
|
+
const extensions = extensionPart.replace('{', '').replace('}', '').split(',');
|
|
176
|
+
return extensions.some(ext => filename.endsWith('.' + ext.trim()));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return filename.includes(pattern.replace('**/', ''));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function shouldIgnore(filePath) {
|
|
183
|
+
return ignorePatterns.some(pattern => {
|
|
184
|
+
if (pattern.includes('**/')) {
|
|
185
|
+
const patternEnd = pattern.replace('**/', '');
|
|
186
|
+
return filePath.includes('/' + patternEnd) || filePath.includes('\\' + patternEnd);
|
|
187
|
+
}
|
|
188
|
+
return filePath.includes(pattern);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function findFiles(dir, results = []) {
|
|
193
|
+
try {
|
|
194
|
+
const items = fs.readdirSync(dir);
|
|
195
|
+
|
|
196
|
+
for (const item of items) {
|
|
197
|
+
const fullPath = path.join(dir, item);
|
|
198
|
+
const relativePath = path.relative(cwd, fullPath);
|
|
199
|
+
|
|
200
|
+
if (shouldIgnore(relativePath)) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
const stat = fs.statSync(fullPath);
|
|
206
|
+
|
|
207
|
+
if (stat.isDirectory()) {
|
|
208
|
+
findFiles(fullPath, results);
|
|
209
|
+
} else if (stat.isFile()) {
|
|
210
|
+
// Check if file matches any of our patterns
|
|
211
|
+
for (const pattern of patterns) {
|
|
212
|
+
if (matchesPattern(item, pattern)) {
|
|
213
|
+
results.push(relativePath);
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
} catch (error) {
|
|
219
|
+
// Skip files we can't access
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
} catch (error) {
|
|
224
|
+
// Skip directories we can't access
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return results;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return findFiles(cwd);
|
|
231
|
+
}
|
|
232
|
+
|
|
159
233
|
async function detectEnvironmentAndFramework() {
|
|
234
|
+
// Defensive check to ensure SecurityUtils is available
|
|
235
|
+
if (!SecurityUtils) {
|
|
236
|
+
throw new Error('SecurityUtils is not available. This may indicate a module loading issue.');
|
|
237
|
+
}
|
|
238
|
+
const fs = require('fs');
|
|
239
|
+
const path = require('path');
|
|
240
|
+
|
|
241
|
+
|
|
160
242
|
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
161
243
|
const pyprojectPath = path.join(process.cwd(), 'pyproject.toml');
|
|
162
244
|
const requirementsPath = path.join(process.cwd(), 'requirements.txt');
|
|
@@ -167,10 +249,10 @@ async function detectEnvironmentAndFramework() {
|
|
|
167
249
|
let detectedLanguage = 'generic';
|
|
168
250
|
let detectedFramework = 'generic';
|
|
169
251
|
|
|
170
|
-
if (
|
|
252
|
+
if (SecurityUtils.safeExistsSync(packageJsonPath)) {
|
|
171
253
|
detectedLanguage = 'javascript';
|
|
172
254
|
try {
|
|
173
|
-
const packageJson = JSON.parse(
|
|
255
|
+
const packageJson = JSON.parse(SecurityUtils.safeReadFileSync(packageJsonPath, path.dirname(packageJsonPath), 'utf8'));
|
|
174
256
|
const deps = {
|
|
175
257
|
...(packageJson.dependencies || {}),
|
|
176
258
|
...(packageJson.devDependencies || {}),
|
|
@@ -189,7 +271,7 @@ async function detectEnvironmentAndFramework() {
|
|
|
189
271
|
/require\(['\"]i18ntk[\/\\]runtime['\"]\)/
|
|
190
272
|
];
|
|
191
273
|
|
|
192
|
-
const sourceFiles = await
|
|
274
|
+
const sourceFiles = await customGlob(['src/**/*.{js,jsx,ts,tsx}'], {
|
|
193
275
|
cwd: process.cwd(),
|
|
194
276
|
ignore: ['**/node_modules/**', '**/dist/**', '**/build/**']
|
|
195
277
|
});
|
|
@@ -223,11 +305,11 @@ async function detectEnvironmentAndFramework() {
|
|
|
223
305
|
} catch (error) {
|
|
224
306
|
detectedFramework = 'generic';
|
|
225
307
|
}
|
|
226
|
-
} else if (
|
|
308
|
+
} else if (SecurityUtils.safeExistsSync(pyprojectPath) || SecurityUtils.safeExistsSync(requirementsPath)) {
|
|
227
309
|
detectedLanguage = 'python';
|
|
228
310
|
try {
|
|
229
|
-
if (
|
|
230
|
-
const requirements =
|
|
311
|
+
if (SecurityUtils.safeExistsSync(requirementsPath)) {
|
|
312
|
+
const requirements = SecurityUtils.safeReadFileSync(requirementsPath, path.dirname(requirementsPath), 'utf8');
|
|
231
313
|
if (requirements.includes('django')) detectedFramework = 'django';
|
|
232
314
|
else if (requirements.includes('flask')) detectedFramework = 'flask';
|
|
233
315
|
else if (requirements.includes('fastapi')) detectedFramework = 'fastapi';
|
|
@@ -236,13 +318,13 @@ async function detectEnvironmentAndFramework() {
|
|
|
236
318
|
} catch (error) {
|
|
237
319
|
detectedFramework = 'generic';
|
|
238
320
|
}
|
|
239
|
-
} else if (
|
|
321
|
+
} else if (SecurityUtils.safeExistsSync(goModPath)) {
|
|
240
322
|
detectedLanguage = 'go';
|
|
241
323
|
detectedFramework = 'generic';
|
|
242
|
-
} else if (
|
|
324
|
+
} else if (SecurityUtils.safeExistsSync(pomPath)) {
|
|
243
325
|
detectedLanguage = 'java';
|
|
244
326
|
try {
|
|
245
|
-
const pomContent =
|
|
327
|
+
const pomContent = SecurityUtils.safeReadFileSync(pomPath, path.dirname(pomPath), 'utf8');
|
|
246
328
|
if (pomContent.includes('spring-boot')) detectedFramework = 'spring-boot';
|
|
247
329
|
else if (pomContent.includes('spring')) detectedFramework = 'spring';
|
|
248
330
|
else if (pomContent.includes('quarkus')) detectedFramework = 'quarkus';
|
|
@@ -250,10 +332,10 @@ async function detectEnvironmentAndFramework() {
|
|
|
250
332
|
} catch (error) {
|
|
251
333
|
detectedFramework = 'generic';
|
|
252
334
|
}
|
|
253
|
-
} else if (
|
|
335
|
+
} else if (SecurityUtils.safeExistsSync(composerPath)) {
|
|
254
336
|
detectedLanguage = 'php';
|
|
255
337
|
try {
|
|
256
|
-
const composer = JSON.parse(
|
|
338
|
+
const composer = JSON.parse(SecurityUtils.safeReadFileSync(composerPath, path.dirname(composerPath), 'utf8'));
|
|
257
339
|
const deps = composer.require || {};
|
|
258
340
|
|
|
259
341
|
if (deps['laravel/framework']) detectedFramework = 'laravel';
|
|
@@ -461,7 +543,7 @@ class I18nManager {
|
|
|
461
543
|
// Only auto-detect if no settings are configured
|
|
462
544
|
for (const possiblePath of possibleI18nPaths) {
|
|
463
545
|
const resolvedPath = path.resolve(projectRoot, possiblePath);
|
|
464
|
-
if (
|
|
546
|
+
if (SecurityUtils.safeExistsSync(resolvedPath)) {
|
|
465
547
|
// Check if it contains language directories
|
|
466
548
|
try {
|
|
467
549
|
const items = fs.readdirSync(resolvedPath);
|
|
@@ -487,13 +569,13 @@ class I18nManager {
|
|
|
487
569
|
async checkI18nDependencies() {
|
|
488
570
|
const packageJsonPath = path.resolve('./package.json');
|
|
489
571
|
|
|
490
|
-
if (!
|
|
572
|
+
if (!SecurityUtils.safeExistsSync(packageJsonPath)) {
|
|
491
573
|
console.log(this.ui ? this.ui.t('errors.noPackageJson') : 'No package.json found');
|
|
492
574
|
return false; // Treat as no framework detected
|
|
493
575
|
}
|
|
494
576
|
|
|
495
577
|
try {
|
|
496
|
-
const packageJson = JSON.parse(
|
|
578
|
+
const packageJson = JSON.parse(SecurityUtils.safeReadFileSync(packageJsonPath, path.dirname(packageJsonPath), 'utf8'));
|
|
497
579
|
// Include peerDependencies in the check
|
|
498
580
|
const dependencies = {
|
|
499
581
|
...packageJson.dependencies,
|
|
@@ -610,12 +692,29 @@ class I18nManager {
|
|
|
610
692
|
|
|
611
693
|
// Add this run method after the checkI18nDependencies method
|
|
612
694
|
async run() {
|
|
695
|
+
// Add timeout to prevent hanging
|
|
696
|
+
const args = this.parseArgs();
|
|
697
|
+
|
|
698
|
+
const timeout = setTimeout(() => {
|
|
699
|
+
console.error('ā CLI startup timeout - something is hanging');
|
|
700
|
+
if (args.debug) {
|
|
701
|
+
console.error('š DEBUG: Last known execution point reached');
|
|
702
|
+
}
|
|
703
|
+
process.exit(1);
|
|
704
|
+
}, 10000); // 10 second timeout
|
|
705
|
+
|
|
706
|
+
if (args.debug) {
|
|
707
|
+
console.log('š DEBUG: Starting i18ntk-manage.js...');
|
|
708
|
+
console.log('š DEBUG: Process.argv:', process.argv);
|
|
709
|
+
console.log('š DEBUG: Parsed args:', args);
|
|
710
|
+
console.log('š DEBUG: About to call SetupEnforcer.checkSetupCompleteAsync()');
|
|
711
|
+
}
|
|
712
|
+
|
|
613
713
|
let prompt;
|
|
614
714
|
try {
|
|
615
715
|
// Ensure setup is complete before running any operations
|
|
616
716
|
await SetupEnforcer.checkSetupCompleteAsync();
|
|
617
|
-
|
|
618
|
-
const args = this.parseArgs();
|
|
717
|
+
|
|
619
718
|
prompt = createPrompt({ noPrompt: args.noPrompt || Boolean(args.adminPin) });
|
|
620
719
|
const interactive = isInteractive({ noPrompt: args.noPrompt || Boolean(args.adminPin) });
|
|
621
720
|
|
|
@@ -1186,7 +1285,7 @@ class I18nManager {
|
|
|
1186
1285
|
console.log(t('debug.runningDebugTool', { displayName }));
|
|
1187
1286
|
try {
|
|
1188
1287
|
const toolPath = path.join(__dirname, '..', 'scripts', 'debug', toolName);
|
|
1189
|
-
if (
|
|
1288
|
+
if (SecurityUtils.safeExistsSync(toolPath)) {
|
|
1190
1289
|
console.log(`Debug tool available: ${toolName}`);
|
|
1191
1290
|
console.log(`To run this tool manually: node "${toolPath}"`);
|
|
1192
1291
|
console.log(`Working directory: ${path.join(__dirname, '..')}`);
|
|
@@ -1209,7 +1308,7 @@ class I18nManager {
|
|
|
1209
1308
|
|
|
1210
1309
|
try {
|
|
1211
1310
|
const logsDir = path.join(__dirname, '..', 'scripts', 'debug', 'logs');
|
|
1212
|
-
if (
|
|
1311
|
+
if (SecurityUtils.safeExistsSync(logsDir)) {
|
|
1213
1312
|
const files = fs.readdirSync(logsDir)
|
|
1214
1313
|
.filter(file => file.endsWith('.log') || file.endsWith('.txt'))
|
|
1215
1314
|
.sort((a, b) => {
|
|
@@ -1230,7 +1329,7 @@ class I18nManager {
|
|
|
1230
1329
|
const fileIndex = parseInt(choice) - 1;
|
|
1231
1330
|
|
|
1232
1331
|
if (fileIndex >= 0 && fileIndex < files.length) {
|
|
1233
|
-
const logContent =
|
|
1332
|
+
const logContent = SecurityUtils.safeReadFileSync(path.join(logsDir, files[fileIndex]), logsDir, 'utf8');
|
|
1234
1333
|
console.log(`\n${t('debug.contentOf', { filename: files[fileIndex] })}:`);
|
|
1235
1334
|
console.log('============================================================');
|
|
1236
1335
|
console.log(logContent.slice(-2000)); // Show last 2000 characters
|
|
@@ -1290,7 +1389,7 @@ class I18nManager {
|
|
|
1290
1389
|
|
|
1291
1390
|
// Check which directories exist and have files
|
|
1292
1391
|
for (const dir of targetDirs) {
|
|
1293
|
-
if (
|
|
1392
|
+
if (SecurityUtils.safeExistsSync(dir.path)) {
|
|
1294
1393
|
const files = this.getAllReportFiles(dir.path);
|
|
1295
1394
|
if (files.length > 0) {
|
|
1296
1395
|
availableDirs.push({
|
|
@@ -1429,7 +1528,7 @@ class I18nManager {
|
|
|
1429
1528
|
let files = [];
|
|
1430
1529
|
|
|
1431
1530
|
try {
|
|
1432
|
-
if (!
|
|
1531
|
+
if (!SecurityUtils.safeExistsSync(dir)) {
|
|
1433
1532
|
return [];
|
|
1434
1533
|
}
|
|
1435
1534
|
|
|
@@ -1561,7 +1660,7 @@ if (require.main === module) {
|
|
|
1561
1660
|
if (args.includes('--version') || args.includes('-v')) {
|
|
1562
1661
|
try {
|
|
1563
1662
|
const packageJsonPath = path.resolve(__dirname, '../package.json');
|
|
1564
|
-
const packageJson = JSON.parse(
|
|
1663
|
+
const packageJson = JSON.parse(SecurityUtils.safeReadFileSync(packageJsonPath, path.dirname(packageJsonPath), 'utf8'));
|
|
1565
1664
|
const versionInfo = packageJson.versionInfo || {};
|
|
1566
1665
|
|
|
1567
1666
|
console.log(`\nš i18n Toolkit (i18ntk)`);
|
|
@@ -1592,4 +1691,4 @@ if (require.main === module) {
|
|
|
1592
1691
|
manager.run();
|
|
1593
1692
|
}
|
|
1594
1693
|
|
|
1595
|
-
module.exports = I18nManager;
|
|
1694
|
+
module.exports = I18nManager;
|