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.
- package/README.md +87 -50
- package/main/i18ntk-analyze.js +63 -63
- package/main/i18ntk-backup-class.js +37 -41
- package/main/i18ntk-backup.js +28 -30
- package/main/i18ntk-complete.js +75 -74
- package/main/i18ntk-doctor.js +7 -6
- package/main/i18ntk-fixer.js +3 -3
- package/main/i18ntk-init.js +49 -13
- package/main/i18ntk-scanner.js +2 -2
- package/main/i18ntk-sizing.js +36 -37
- package/main/i18ntk-summary.js +4 -4
- package/main/i18ntk-ui.js +95 -96
- package/main/i18ntk-usage.js +31 -19
- package/main/i18ntk-validate.js +78 -27
- package/main/manage/commands/AnalyzeCommand.js +71 -73
- package/main/manage/commands/CommandRouter.js +15 -12
- package/main/manage/commands/FixerCommand.js +94 -38
- package/main/manage/commands/ScannerCommand.js +2 -2
- package/main/manage/commands/ValidateCommand.js +87 -36
- package/main/manage/index.js +165 -152
- package/main/manage/managers/DebugMenu.js +6 -6
- package/main/manage/managers/InteractiveMenu.js +6 -6
- package/main/manage/managers/LanguageMenu.js +12 -6
- package/main/manage/managers/SettingsMenu.js +6 -6
- package/main/manage/services/AuthenticationService.js +5 -6
- package/main/manage/services/ConfigurationService.js +22 -34
- package/main/manage/services/FileManagementService.js +6 -6
- package/main/manage/services/InitService.js +44 -8
- package/main/manage/services/UsageService.js +24 -12
- package/package.json +21 -42
- package/settings/settings-cli.js +5 -5
- package/settings/settings-manager.js +984 -968
- package/ui-locales/de.json +12 -11
- package/ui-locales/en.json +12 -11
- package/ui-locales/es.json +12 -11
- package/ui-locales/fr.json +12 -11
- package/ui-locales/ja.json +12 -11
- package/ui-locales/ru.json +12 -11
- package/ui-locales/zh.json +12 -11
- package/utils/config-helper.js +27 -16
- package/utils/config-manager.js +8 -7
- package/utils/i18n-helper.js +161 -166
- package/utils/init-helper.js +3 -2
- package/utils/json-output.js +11 -10
- package/{scripts → utils}/locale-optimizer.js +61 -60
- package/utils/logger.js +4 -4
- package/utils/safe-json.js +3 -3
- package/utils/secure-backup.js +8 -7
- package/utils/setup-enforcer.js +63 -98
- package/main/i18ntk-go.js +0 -283
- package/main/i18ntk-java.js +0 -380
- package/main/i18ntk-js.js +0 -512
- package/main/i18ntk-manage.js +0 -1694
- package/main/i18ntk-php.js +0 -462
- package/main/i18ntk-py.js +0 -379
- package/main/i18ntk-settings.js +0 -23
- package/main/manage/index-fixed.js +0 -1447
- package/scripts/build-lite.js +0 -279
- package/scripts/deprecate-versions.js +0 -317
- package/scripts/export-translations.js +0 -84
- package/scripts/fix-all-i18n.js +0 -236
- package/scripts/fix-and-purify-i18n.js +0 -233
- package/scripts/fix-locale-control-chars.js +0 -110
- package/scripts/lint-locales.js +0 -80
- package/scripts/prepublish-dev.js +0 -221
- package/scripts/prepublish.js +0 -362
- package/scripts/security-check.js +0 -117
- package/scripts/sync-translations.js +0 -151
- package/scripts/sync-ui-locales.js +0 -20
- package/scripts/validate-all-translations.js +0 -195
- package/scripts/verify-deprecations.js +0 -157
- package/scripts/verify-translations.js +0 -63
- package/utils/security-fixed.js +0 -609
package/utils/i18n-helper.js
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
// utils/i18n-helper.js
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
4
4
|
|
|
5
5
|
// Lazy load SecurityUtils to prevent circular dependencies
|
|
6
6
|
let securityUtils;
|
|
7
|
-
function getSecurityUtils() {
|
|
8
|
-
if (!securityUtils) {
|
|
9
|
-
try {
|
|
10
|
-
securityUtils = require('./security');
|
|
11
|
-
} catch (error) {
|
|
12
|
-
// Fallback: use basic fs operations if SecurityUtils is not available
|
|
13
|
-
return {
|
|
14
|
-
safeExistsSync: (targetPath) => {
|
|
15
|
-
try {
|
|
16
|
-
require('fs').accessSync(targetPath);
|
|
17
|
-
return true;
|
|
18
|
-
} catch {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
safeWriteFileSync: (targetPath, data, _basePath, encoding = 'utf8') => {
|
|
23
|
-
try {
|
|
24
|
-
return require('fs').writeFileSync(targetPath, data, encoding);
|
|
25
|
-
} catch {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
safeReadFileSync: (targetPath, _basePath, encoding = 'utf8') => {
|
|
30
|
-
try {
|
|
31
|
-
return require('fs').readFileSync(targetPath, encoding);
|
|
32
|
-
} catch {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
};
|
|
7
|
+
function getSecurityUtils() {
|
|
8
|
+
if (!securityUtils) {
|
|
9
|
+
try {
|
|
10
|
+
securityUtils = require('./security');
|
|
11
|
+
} catch (error) {
|
|
12
|
+
// Fallback: use basic fs operations if SecurityUtils is not available
|
|
13
|
+
return {
|
|
14
|
+
safeExistsSync: (targetPath) => {
|
|
15
|
+
try {
|
|
16
|
+
require('fs').accessSync(targetPath);
|
|
17
|
+
return true;
|
|
18
|
+
} catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
safeWriteFileSync: (targetPath, data, _basePath, encoding = 'utf8') => {
|
|
23
|
+
try {
|
|
24
|
+
return require('fs').writeFileSync(targetPath, data, encoding);
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
safeReadFileSync: (targetPath, _basePath, encoding = 'utf8') => {
|
|
30
|
+
try {
|
|
31
|
+
return require('fs').readFileSync(targetPath, encoding);
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
return securityUtils;
|
|
@@ -50,105 +50,100 @@ function safeRequireConfig() {
|
|
|
50
50
|
try { return require('./config-manager'); } catch { return null; }
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
function stripBOMAndComments(s) {
|
|
54
|
-
if (s.charCodeAt(0) === 0xFEFF) s = s.slice(1);
|
|
55
|
-
s = s.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
56
|
-
s = s.replace(/^\s*\/\/.*$/mg, '');
|
|
57
|
-
return s;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function getValidationBase(targetPath) {
|
|
61
|
-
const fallbackBase = path.resolve(__dirname, '..');
|
|
62
|
-
if (!targetPath || typeof targetPath !== 'string') {
|
|
63
|
-
return fallbackBase;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
let current = path.resolve(path.dirname(targetPath));
|
|
67
|
-
while (true) {
|
|
68
|
-
try {
|
|
69
|
-
if (fs.statSync(current).isDirectory()) {
|
|
70
|
-
return current;
|
|
71
|
-
}
|
|
72
|
-
} catch {
|
|
73
|
-
// Continue upward until we find an existing directory.
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const parent = path.dirname(current);
|
|
77
|
-
if (parent === current) {
|
|
78
|
-
break;
|
|
79
|
-
}
|
|
80
|
-
current = parent;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return fallbackBase;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function safeReadFile(targetPath, encoding = 'utf8') {
|
|
87
|
-
const SecurityUtils = getSecurityUtils();
|
|
88
|
-
return SecurityUtils.safeReadFileSync(targetPath, getValidationBase(targetPath), encoding);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function readJsonSafe(file) {
|
|
92
|
-
const raw = safeReadFile(file, 'utf8');
|
|
93
|
-
if (raw === null) {
|
|
94
|
-
throw new Error(`Unable to read JSON file: ${file}`);
|
|
95
|
-
}
|
|
96
|
-
return JSON.parse(stripBOMAndComments(raw));
|
|
97
|
-
}
|
|
53
|
+
function stripBOMAndComments(s) {
|
|
54
|
+
if (s.charCodeAt(0) === 0xFEFF) s = s.slice(1);
|
|
55
|
+
s = s.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
56
|
+
s = s.replace(/^\s*\/\/.*$/mg, '');
|
|
57
|
+
return s;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getValidationBase(targetPath) {
|
|
61
|
+
const fallbackBase = path.resolve(__dirname, '..');
|
|
62
|
+
if (!targetPath || typeof targetPath !== 'string') {
|
|
63
|
+
return fallbackBase;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let current = path.resolve(path.dirname(targetPath));
|
|
67
|
+
while (true) {
|
|
68
|
+
try {
|
|
69
|
+
if (fs.statSync(current).isDirectory()) {
|
|
70
|
+
return current;
|
|
71
|
+
}
|
|
72
|
+
} catch {
|
|
73
|
+
// Continue upward until we find an existing directory.
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const parent = path.dirname(current);
|
|
77
|
+
if (parent === current) {
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
current = parent;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return fallbackBase;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function safeReadFile(targetPath, encoding = 'utf8') {
|
|
87
|
+
const SecurityUtils = getSecurityUtils();
|
|
88
|
+
return SecurityUtils.safeReadFileSync(targetPath, getValidationBase(targetPath), encoding);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function readJsonSafe(file) {
|
|
92
|
+
const raw = safeReadFile(file, 'utf8');
|
|
93
|
+
if (raw === null) {
|
|
94
|
+
throw new Error(`Unable to read JSON file: ${file}`);
|
|
95
|
+
}
|
|
96
|
+
return JSON.parse(stripBOMAndComments(raw));
|
|
97
|
+
}
|
|
98
98
|
|
|
99
99
|
function pkgUiLocalesDirViaThisFile() {
|
|
100
100
|
return path.resolve(__dirname, '..', 'ui-locales');
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
function pkgUiLocalesDirViaResolve() {
|
|
103
|
+
function pkgUiLocalesDirViaResolve() {
|
|
104
104
|
try {
|
|
105
105
|
// Try the new correct path first (ui-locales/en.json)
|
|
106
106
|
const enJson = require.resolve('i18ntk/ui-locales/en.json');
|
|
107
107
|
return path.dirname(enJson);
|
|
108
108
|
} catch {
|
|
109
|
-
try {
|
|
110
|
-
// Fallback to the old incorrect path for backward compatibility
|
|
111
|
-
const enJson = require.resolve('i18ntk/resources/i18n/ui-locales/en.json');
|
|
112
|
-
return path.dirname(enJson);
|
|
113
|
-
} catch { return null; }
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const legacyDir = legacyResourcesUiLocalesDir();
|
|
149
|
-
if (legacyDir !== pkgA && legacyDir !== pkgB) {
|
|
150
|
-
addDir(legacyDir);
|
|
151
|
-
}
|
|
109
|
+
try {
|
|
110
|
+
// Fallback to the old incorrect path for backward compatibility
|
|
111
|
+
const enJson = require.resolve('i18ntk/resources/i18n/ui-locales/en.json');
|
|
112
|
+
return path.dirname(enJson);
|
|
113
|
+
} catch { return null; }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Removed legacyResourcesUiLocalesDir as resources/i18n/ui-locales is deprecated
|
|
118
|
+
|
|
119
|
+
function resolveLocalesDirs(preferredDir) {
|
|
120
|
+
const SecurityUtils = getSecurityUtils();
|
|
121
|
+
const dirs = [];
|
|
122
|
+
const addDir = (dir) => {
|
|
123
|
+
if (typeof dir === 'string' && dir.trim()) {
|
|
124
|
+
try {
|
|
125
|
+
const normalized = path.normalize(path.resolve(dir.trim()));
|
|
126
|
+
const stats = SecurityUtils.safeStatSync(normalized, getValidationBase(normalized));
|
|
127
|
+
if (stats && stats.isDirectory()) {
|
|
128
|
+
dirs.push(normalized);
|
|
129
|
+
}
|
|
130
|
+
} catch {
|
|
131
|
+
// Silently ignore invalid paths
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
addDir(preferredDir);
|
|
137
|
+
|
|
138
|
+
const pkgA = pkgUiLocalesDirViaThisFile();
|
|
139
|
+
addDir(pkgA);
|
|
140
|
+
|
|
141
|
+
const pkgB = pkgUiLocalesDirViaResolve();
|
|
142
|
+
if (pkgB && pkgB !== pkgA) {
|
|
143
|
+
addDir(pkgB);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Removed legacy directory fallback
|
|
152
147
|
|
|
153
148
|
// Deduplicate while preserving order
|
|
154
149
|
const seen = new Set();
|
|
@@ -166,9 +161,9 @@ function candidatesForLang(dir, lang) {
|
|
|
166
161
|
];
|
|
167
162
|
}
|
|
168
163
|
|
|
169
|
-
function findLocaleFilesAllDirs(lang, preferredDir) {
|
|
170
|
-
const SecurityUtils = getSecurityUtils();
|
|
171
|
-
const dirs = resolveLocalesDirs(preferredDir);
|
|
164
|
+
function findLocaleFilesAllDirs(lang, preferredDir) {
|
|
165
|
+
const SecurityUtils = getSecurityUtils();
|
|
166
|
+
const dirs = resolveLocalesDirs(preferredDir);
|
|
172
167
|
|
|
173
168
|
if (process.env.I18NTK_DEBUG_LOCALES === '1') {
|
|
174
169
|
console.log('🔎 i18ntk locale search dirs:', dirs);
|
|
@@ -177,29 +172,29 @@ function findLocaleFilesAllDirs(lang, preferredDir) {
|
|
|
177
172
|
const files = [];
|
|
178
173
|
const errors = [];
|
|
179
174
|
|
|
180
|
-
for (const dir of dirs) {
|
|
181
|
-
for (const candidate of candidatesForLang(dir, lang)) {
|
|
182
|
-
try {
|
|
183
|
-
const stats = SecurityUtils.safeStatSync(candidate, getValidationBase(candidate));
|
|
184
|
-
if (stats && stats.isFile() && stats.size > 0) {
|
|
185
|
-
// Validate file is readable and parseable
|
|
186
|
-
fs.accessSync(candidate, fs.constants.R_OK);
|
|
187
|
-
// Quick JSON validation
|
|
188
|
-
const content = safeReadFile(candidate, 'utf8');
|
|
189
|
-
if (content) {
|
|
190
|
-
if (content.trim().startsWith('{') || content.trim().startsWith('[')) {
|
|
191
|
-
files.push(candidate);
|
|
192
|
-
} else {
|
|
193
|
-
errors.push({ file: candidate, error: 'Invalid JSON format' });
|
|
194
|
-
}
|
|
195
|
-
} else {
|
|
196
|
-
errors.push({ file: candidate, error: 'Empty or unreadable file' });
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
} catch (error) {
|
|
200
|
-
errors.push({ file: candidate, error: error.message });
|
|
201
|
-
}
|
|
202
|
-
}
|
|
175
|
+
for (const dir of dirs) {
|
|
176
|
+
for (const candidate of candidatesForLang(dir, lang)) {
|
|
177
|
+
try {
|
|
178
|
+
const stats = SecurityUtils.safeStatSync(candidate, getValidationBase(candidate));
|
|
179
|
+
if (stats && stats.isFile() && stats.size > 0) {
|
|
180
|
+
// Validate file is readable and parseable
|
|
181
|
+
fs.accessSync(candidate, fs.constants.R_OK);
|
|
182
|
+
// Quick JSON validation
|
|
183
|
+
const content = safeReadFile(candidate, 'utf8');
|
|
184
|
+
if (content) {
|
|
185
|
+
if (content.trim().startsWith('{') || content.trim().startsWith('[')) {
|
|
186
|
+
files.push(candidate);
|
|
187
|
+
} else {
|
|
188
|
+
errors.push({ file: candidate, error: 'Invalid JSON format' });
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
errors.push({ file: candidate, error: 'Empty or unreadable file' });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
} catch (error) {
|
|
195
|
+
errors.push({ file: candidate, error: error.message });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
203
198
|
}
|
|
204
199
|
|
|
205
200
|
if (process.env.I18NTK_DEBUG_LOCALES === '1' && errors.length > 0) {
|
|
@@ -214,7 +209,7 @@ let currentLanguage = 'en';
|
|
|
214
209
|
let isInitialized = false;
|
|
215
210
|
const missingWarned = new Set();
|
|
216
211
|
|
|
217
|
-
function loadTranslations(language) {
|
|
212
|
+
function loadTranslations(language) {
|
|
218
213
|
const cfg = safeRequireConfig();
|
|
219
214
|
const settings = cfg?.getConfig?.() || {};
|
|
220
215
|
const configuredLanguage = settings.uiLanguage || settings.language;
|
|
@@ -226,10 +221,10 @@ function loadTranslations(language) {
|
|
|
226
221
|
|
|
227
222
|
const loadErrors = [];
|
|
228
223
|
|
|
229
|
-
const preferredDir = arguments.length > 1 ? arguments[1] : null;
|
|
230
|
-
|
|
231
|
-
for (const lang of tryOrder) {
|
|
232
|
-
const files = findLocaleFilesAllDirs(lang, preferredDir);
|
|
224
|
+
const preferredDir = arguments.length > 1 ? arguments[1] : null;
|
|
225
|
+
|
|
226
|
+
for (const lang of tryOrder) {
|
|
227
|
+
const files = findLocaleFilesAllDirs(lang, preferredDir);
|
|
233
228
|
|
|
234
229
|
// Prioritize bundled locales over project ones
|
|
235
230
|
const prioritizedFiles = files.sort((a, b) => Number(isBundledPath(b)) - Number(isBundledPath(a)));
|
|
@@ -402,20 +397,20 @@ function getCurrentLanguage() {
|
|
|
402
397
|
function getAvailableLanguages() {
|
|
403
398
|
const dirs = resolveLocalesDirs();
|
|
404
399
|
const langs = new Set();
|
|
405
|
-
for (const d of dirs) {
|
|
406
|
-
try {
|
|
407
|
-
const SecurityUtils = getSecurityUtils();
|
|
408
|
-
if (!SecurityUtils.safeExistsSync(d, getValidationBase(d))) continue;
|
|
409
|
-
for (const f of fs.readdirSync(d)) {
|
|
410
|
-
if (f.endsWith('.json')) langs.add(path.basename(f, '.json'));
|
|
411
|
-
}
|
|
412
|
-
for (const f of fs.readdirSync(d, { withFileTypes: true })) {
|
|
413
|
-
const nestedPath = path.join(d, f.name, `${f.name}.json`);
|
|
414
|
-
if (f.isDirectory() && SecurityUtils.safeExistsSync(nestedPath, getValidationBase(nestedPath))) {
|
|
415
|
-
langs.add(f.name);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
} catch {}
|
|
400
|
+
for (const d of dirs) {
|
|
401
|
+
try {
|
|
402
|
+
const SecurityUtils = getSecurityUtils();
|
|
403
|
+
if (!SecurityUtils.safeExistsSync(d, getValidationBase(d))) continue;
|
|
404
|
+
for (const f of fs.readdirSync(d)) {
|
|
405
|
+
if (f.endsWith('.json')) langs.add(path.basename(f, '.json'));
|
|
406
|
+
}
|
|
407
|
+
for (const f of fs.readdirSync(d, { withFileTypes: true })) {
|
|
408
|
+
const nestedPath = path.join(d, f.name, `${f.name}.json`);
|
|
409
|
+
if (f.isDirectory() && SecurityUtils.safeExistsSync(nestedPath, getValidationBase(nestedPath))) {
|
|
410
|
+
langs.add(f.name);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
} catch {}
|
|
419
414
|
}
|
|
420
415
|
return Array.from(langs.size ? langs : new Set(['en']));
|
|
421
416
|
}
|
package/utils/init-helper.js
CHANGED
|
@@ -2,6 +2,7 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const configManager = require('./config-manager');
|
|
4
4
|
const SecurityUtils = require('./security');
|
|
5
|
+
const packageJson = require('../package.json');
|
|
5
6
|
|
|
6
7
|
function ensureDirectory(dirPath) {
|
|
7
8
|
if (!dirPath || typeof dirPath !== 'string') return;
|
|
@@ -46,7 +47,7 @@ function hasSourceLanguageFiles(sourceDir, sourceLanguage) {
|
|
|
46
47
|
*/
|
|
47
48
|
async function checkInitialized(options = {}) {
|
|
48
49
|
const settings = configManager.getConfig ? configManager.getConfig() : {};
|
|
49
|
-
const currentVersion =
|
|
50
|
+
const currentVersion = packageJson.version;
|
|
50
51
|
const projectConfigPath = configManager.CONFIG_PATH || path.join(process.cwd(), '.i18ntk-config');
|
|
51
52
|
const configDir = path.dirname(projectConfigPath);
|
|
52
53
|
|
|
@@ -135,7 +136,7 @@ async function markAsInitialized(config) {
|
|
|
135
136
|
const projectConfigPath = configManager.CONFIG_PATH || path.join(process.cwd(), '.i18ntk-config');
|
|
136
137
|
const configDir = path.dirname(projectConfigPath);
|
|
137
138
|
const initFilePath = path.join(configDir, 'initialization.json');
|
|
138
|
-
const currentVersion =
|
|
139
|
+
const currentVersion = packageJson.version;
|
|
139
140
|
const now = new Date().toISOString();
|
|
140
141
|
const sourceDir = config?.sourceDir || settings.sourceDir || './locales';
|
|
141
142
|
const sourceLanguage = config?.sourceLanguage || settings.sourceLanguage || 'en';
|
package/utils/json-output.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
const packageJson = require('../package.json');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* JSON Output Utility for i18ntk commands
|
|
5
|
+
* Provides consistent machine-readable output format for CI/CD integration
|
|
4
6
|
*/
|
|
5
7
|
|
|
6
8
|
class JsonOutput {
|
|
@@ -21,12 +23,11 @@ class JsonOutput {
|
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
getPackageVersion() {
|
|
25
|
-
try {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return '1.8.3';
|
|
26
|
+
getPackageVersion() {
|
|
27
|
+
try {
|
|
28
|
+
return packageJson.version;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
return '1.8.3';
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -96,4 +97,4 @@ class JsonOutput {
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
module.exports = JsonOutput;
|
|
100
|
+
module.exports = JsonOutput;
|