poly-lexis 0.1.0 → 0.2.1
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 +24 -24
- package/dist/cli/translations.js +353 -80
- package/dist/cli/translations.js.map +1 -1
- package/dist/index.d.ts +211 -108
- package/dist/index.js +632 -355
- package/dist/index.js.map +1 -1
- package/dist/translations/core/translations-config.schema.json +252 -32
- package/package.json +5 -6
package/dist/index.js
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
-
}) : x)(function(x) {
|
|
6
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
-
});
|
|
9
3
|
var __esm = (fn, res) => function __init() {
|
|
10
4
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
5
|
};
|
|
@@ -14,33 +8,84 @@ var __export = (target, all) => {
|
|
|
14
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
15
9
|
};
|
|
16
10
|
|
|
17
|
-
// src/translations/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
// src/translations/utils/utils.ts
|
|
12
|
+
import * as fs from "fs";
|
|
13
|
+
import * as path from "path";
|
|
14
|
+
function readTranslations(translationsPath, language) {
|
|
15
|
+
const langPath = path.join(translationsPath, language);
|
|
16
|
+
if (!fs.existsSync(langPath)) {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
const files = fs.readdirSync(langPath).filter((f) => f.endsWith(".json"));
|
|
20
|
+
const translations = {};
|
|
21
|
+
for (const file of files) {
|
|
22
|
+
const namespace = path.basename(file, ".json");
|
|
23
|
+
const filePath = path.join(langPath, file);
|
|
24
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
25
|
+
translations[namespace] = JSON.parse(content);
|
|
26
|
+
}
|
|
27
|
+
return translations;
|
|
28
|
+
}
|
|
29
|
+
function writeTranslation(translationsPath, language, namespace, translations) {
|
|
30
|
+
const langPath = path.join(translationsPath, language);
|
|
31
|
+
if (!fs.existsSync(langPath)) {
|
|
32
|
+
fs.mkdirSync(langPath, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
const filePath = path.join(langPath, `${namespace}.json`);
|
|
35
|
+
fs.writeFileSync(filePath, `${JSON.stringify(translations, null, 2)}
|
|
36
|
+
`, "utf-8");
|
|
37
|
+
}
|
|
38
|
+
function getAvailableLanguages(translationsPath) {
|
|
39
|
+
if (!fs.existsSync(translationsPath)) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
return fs.readdirSync(translationsPath, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
43
|
+
}
|
|
44
|
+
function getNamespaces(translationsPath, language) {
|
|
45
|
+
const langPath = path.join(translationsPath, language);
|
|
46
|
+
if (!fs.existsSync(langPath)) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
return fs.readdirSync(langPath).filter((f) => f.endsWith(".json")).map((f) => path.basename(f, ".json"));
|
|
50
|
+
}
|
|
51
|
+
function hasInterpolation(text) {
|
|
52
|
+
return /\{\{[^}]+\}\}/g.test(text);
|
|
53
|
+
}
|
|
54
|
+
function extractVariables(text) {
|
|
55
|
+
const matches = text.match(/\{\{([^}]+)\}\}/g);
|
|
56
|
+
if (!matches) return [];
|
|
57
|
+
return matches.map((match) => match.replace(/\{\{|\}\}/g, "").trim());
|
|
58
|
+
}
|
|
59
|
+
function validateVariables(sourceText, translatedText) {
|
|
60
|
+
const sourceVars = extractVariables(sourceText).sort();
|
|
61
|
+
const translatedVars = extractVariables(translatedText).sort();
|
|
62
|
+
if (sourceVars.length !== translatedVars.length) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
return sourceVars.every((v, i) => v === translatedVars[i]);
|
|
66
|
+
}
|
|
67
|
+
function sortKeys(obj) {
|
|
68
|
+
const sorted = {};
|
|
69
|
+
const keys = Object.keys(obj).sort();
|
|
70
|
+
for (const key of keys) {
|
|
71
|
+
sorted[key] = obj[key];
|
|
72
|
+
}
|
|
73
|
+
return sorted;
|
|
74
|
+
}
|
|
75
|
+
function ensureTranslationsStructure(translationsPath, languages) {
|
|
76
|
+
if (!fs.existsSync(translationsPath)) {
|
|
77
|
+
fs.mkdirSync(translationsPath, { recursive: true });
|
|
78
|
+
}
|
|
79
|
+
for (const lang of languages) {
|
|
80
|
+
const langPath = path.join(translationsPath, lang);
|
|
81
|
+
if (!fs.existsSync(langPath)) {
|
|
82
|
+
fs.mkdirSync(langPath, { recursive: true });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
var init_utils = __esm({
|
|
87
|
+
"src/translations/utils/utils.ts"() {
|
|
21
88
|
"use strict";
|
|
22
|
-
DEFAULT_CONFIG = {
|
|
23
|
-
translationsPath: "public/static/locales",
|
|
24
|
-
languages: ["en"],
|
|
25
|
-
sourceLanguage: "en",
|
|
26
|
-
typesOutputPath: "src/types/i18nTypes.ts"
|
|
27
|
-
};
|
|
28
|
-
DEFAULT_LANGUAGES = [
|
|
29
|
-
"en",
|
|
30
|
-
"fr",
|
|
31
|
-
"it",
|
|
32
|
-
"pl",
|
|
33
|
-
"es",
|
|
34
|
-
"pt",
|
|
35
|
-
"de",
|
|
36
|
-
"de_at",
|
|
37
|
-
"nl",
|
|
38
|
-
"sv",
|
|
39
|
-
"hu",
|
|
40
|
-
"cs",
|
|
41
|
-
"ja",
|
|
42
|
-
"zh_hk"
|
|
43
|
-
];
|
|
44
89
|
}
|
|
45
90
|
});
|
|
46
91
|
|
|
@@ -60,54 +105,274 @@ var init_schema = __esm({
|
|
|
60
105
|
"src/translations/core/schema.ts"() {
|
|
61
106
|
"use strict";
|
|
62
107
|
SUPPORTED_LANGUAGES = [
|
|
108
|
+
"af",
|
|
109
|
+
// Afrikaans
|
|
110
|
+
"sq",
|
|
111
|
+
// Albanian
|
|
112
|
+
"am",
|
|
113
|
+
// Amharic
|
|
114
|
+
"ar",
|
|
115
|
+
// Arabic
|
|
116
|
+
"hy",
|
|
117
|
+
// Armenian
|
|
118
|
+
"as",
|
|
119
|
+
// Assamese
|
|
120
|
+
"ay",
|
|
121
|
+
// Aymara
|
|
122
|
+
"az",
|
|
123
|
+
// Azerbaijani
|
|
124
|
+
"bm",
|
|
125
|
+
// Bambara
|
|
126
|
+
"eu",
|
|
127
|
+
// Basque
|
|
128
|
+
"be",
|
|
129
|
+
// Belarusian
|
|
130
|
+
"bn",
|
|
131
|
+
// Bengali
|
|
132
|
+
"bho",
|
|
133
|
+
// Bhojpuri
|
|
134
|
+
"bs",
|
|
135
|
+
// Bosnian
|
|
136
|
+
"bg",
|
|
137
|
+
// Bulgarian
|
|
138
|
+
"ca",
|
|
139
|
+
// Catalan
|
|
140
|
+
"ceb",
|
|
141
|
+
// Cebuano
|
|
142
|
+
"ny",
|
|
143
|
+
// Chichewa
|
|
144
|
+
"zh",
|
|
145
|
+
// Chinese (Simplified) - Google uses 'zh' or 'zh-CN'
|
|
146
|
+
"zh_cn",
|
|
147
|
+
// Chinese (Simplified) - alternative format
|
|
148
|
+
"zh_tw",
|
|
149
|
+
// Chinese (Traditional)
|
|
150
|
+
"co",
|
|
151
|
+
// Corsican
|
|
152
|
+
"hr",
|
|
153
|
+
// Croatian
|
|
154
|
+
"cs",
|
|
155
|
+
// Czech
|
|
156
|
+
"da",
|
|
157
|
+
// Danish
|
|
158
|
+
"dv",
|
|
159
|
+
// Dhivehi
|
|
160
|
+
"doi",
|
|
161
|
+
// Dogri
|
|
162
|
+
"nl",
|
|
163
|
+
// Dutch
|
|
63
164
|
"en",
|
|
64
165
|
// English
|
|
166
|
+
"eo",
|
|
167
|
+
// Esperanto
|
|
168
|
+
"et",
|
|
169
|
+
// Estonian
|
|
170
|
+
"ee",
|
|
171
|
+
// Ewe
|
|
172
|
+
"tl",
|
|
173
|
+
// Filipino (Tagalog)
|
|
174
|
+
"fi",
|
|
175
|
+
// Finnish
|
|
65
176
|
"fr",
|
|
66
177
|
// French
|
|
67
|
-
"
|
|
68
|
-
//
|
|
69
|
-
"
|
|
70
|
-
//
|
|
71
|
-
"es",
|
|
72
|
-
// Spanish
|
|
73
|
-
"pt",
|
|
74
|
-
// Portuguese
|
|
178
|
+
"gl",
|
|
179
|
+
// Galician
|
|
180
|
+
"ka",
|
|
181
|
+
// Georgian
|
|
75
182
|
"de",
|
|
76
183
|
// German
|
|
77
|
-
"
|
|
78
|
-
//
|
|
79
|
-
"
|
|
80
|
-
//
|
|
81
|
-
"
|
|
82
|
-
//
|
|
184
|
+
"el",
|
|
185
|
+
// Greek
|
|
186
|
+
"gn",
|
|
187
|
+
// Guarani
|
|
188
|
+
"gu",
|
|
189
|
+
// Gujarati
|
|
190
|
+
"ht",
|
|
191
|
+
// Haitian Creole
|
|
192
|
+
"ha",
|
|
193
|
+
// Hausa
|
|
194
|
+
"haw",
|
|
195
|
+
// Hawaiian
|
|
196
|
+
"iw",
|
|
197
|
+
// Hebrew (legacy code, 'he' is preferred)
|
|
198
|
+
"he",
|
|
199
|
+
// Hebrew
|
|
200
|
+
"hi",
|
|
201
|
+
// Hindi
|
|
202
|
+
"hmn",
|
|
203
|
+
// Hmong
|
|
83
204
|
"hu",
|
|
84
205
|
// Hungarian
|
|
85
|
-
"
|
|
86
|
-
//
|
|
206
|
+
"is",
|
|
207
|
+
// Icelandic
|
|
208
|
+
"ig",
|
|
209
|
+
// Igbo
|
|
210
|
+
"ilo",
|
|
211
|
+
// Ilocano
|
|
212
|
+
"id",
|
|
213
|
+
// Indonesian
|
|
214
|
+
"ga",
|
|
215
|
+
// Irish
|
|
216
|
+
"it",
|
|
217
|
+
// Italian
|
|
87
218
|
"ja",
|
|
88
219
|
// Japanese
|
|
89
|
-
"
|
|
90
|
-
//
|
|
91
|
-
"
|
|
92
|
-
//
|
|
220
|
+
"jw",
|
|
221
|
+
// Javanese
|
|
222
|
+
"kn",
|
|
223
|
+
// Kannada
|
|
224
|
+
"kk",
|
|
225
|
+
// Kazakh
|
|
226
|
+
"km",
|
|
227
|
+
// Khmer
|
|
228
|
+
"rw",
|
|
229
|
+
// Kinyarwanda
|
|
230
|
+
"gom",
|
|
231
|
+
// Konkani
|
|
93
232
|
"ko",
|
|
94
233
|
// Korean
|
|
234
|
+
"kri",
|
|
235
|
+
// Krio
|
|
236
|
+
"ku",
|
|
237
|
+
// Kurdish (Kurmanji)
|
|
238
|
+
"ckb",
|
|
239
|
+
// Kurdish (Sorani)
|
|
240
|
+
"ky",
|
|
241
|
+
// Kyrgyz
|
|
242
|
+
"lo",
|
|
243
|
+
// Lao
|
|
244
|
+
"la",
|
|
245
|
+
// Latin
|
|
246
|
+
"lv",
|
|
247
|
+
// Latvian
|
|
248
|
+
"ln",
|
|
249
|
+
// Lingala
|
|
250
|
+
"lt",
|
|
251
|
+
// Lithuanian
|
|
252
|
+
"lg",
|
|
253
|
+
// Luganda
|
|
254
|
+
"lb",
|
|
255
|
+
// Luxembourgish
|
|
256
|
+
"mk",
|
|
257
|
+
// Macedonian
|
|
258
|
+
"mai",
|
|
259
|
+
// Maithili
|
|
260
|
+
"mg",
|
|
261
|
+
// Malagasy
|
|
262
|
+
"ms",
|
|
263
|
+
// Malay
|
|
264
|
+
"ml",
|
|
265
|
+
// Malayalam
|
|
266
|
+
"mt",
|
|
267
|
+
// Maltese
|
|
268
|
+
"mi",
|
|
269
|
+
// Maori
|
|
270
|
+
"mr",
|
|
271
|
+
// Marathi
|
|
272
|
+
"mni",
|
|
273
|
+
// Meiteilon (Manipuri)
|
|
274
|
+
"lus",
|
|
275
|
+
// Mizo
|
|
276
|
+
"mn",
|
|
277
|
+
// Mongolian
|
|
278
|
+
"my",
|
|
279
|
+
// Myanmar (Burmese)
|
|
280
|
+
"ne",
|
|
281
|
+
// Nepali
|
|
282
|
+
"no",
|
|
283
|
+
// Norwegian
|
|
284
|
+
"or",
|
|
285
|
+
// Odia
|
|
286
|
+
"om",
|
|
287
|
+
// Oromo
|
|
288
|
+
"ps",
|
|
289
|
+
// Pashto
|
|
290
|
+
"fa",
|
|
291
|
+
// Persian
|
|
292
|
+
"pl",
|
|
293
|
+
// Polish
|
|
294
|
+
"pt",
|
|
295
|
+
// Portuguese
|
|
296
|
+
"pt_br",
|
|
297
|
+
// Portuguese (Brazil)
|
|
298
|
+
"pa",
|
|
299
|
+
// Punjabi
|
|
300
|
+
"qu",
|
|
301
|
+
// Quechua
|
|
302
|
+
"ro",
|
|
303
|
+
// Romanian
|
|
95
304
|
"ru",
|
|
96
305
|
// Russian
|
|
97
|
-
"
|
|
98
|
-
//
|
|
99
|
-
"
|
|
100
|
-
//
|
|
306
|
+
"sm",
|
|
307
|
+
// Samoan
|
|
308
|
+
"sa",
|
|
309
|
+
// Sanskrit
|
|
310
|
+
"gd",
|
|
311
|
+
// Scottish Gaelic
|
|
312
|
+
"sr",
|
|
313
|
+
// Serbian
|
|
314
|
+
"st",
|
|
315
|
+
// Sesotho
|
|
316
|
+
"sn",
|
|
317
|
+
// Shona
|
|
318
|
+
"sd",
|
|
319
|
+
// Sindhi
|
|
320
|
+
"si",
|
|
321
|
+
// Sinhala
|
|
322
|
+
"sk",
|
|
323
|
+
// Slovak
|
|
324
|
+
"sl",
|
|
325
|
+
// Slovenian
|
|
326
|
+
"so",
|
|
327
|
+
// Somali
|
|
328
|
+
"es",
|
|
329
|
+
// Spanish
|
|
330
|
+
"su",
|
|
331
|
+
// Sundanese
|
|
332
|
+
"sw",
|
|
333
|
+
// Swahili
|
|
334
|
+
"sv",
|
|
335
|
+
// Swedish
|
|
336
|
+
"tg",
|
|
337
|
+
// Tajik
|
|
338
|
+
"ta",
|
|
339
|
+
// Tamil
|
|
340
|
+
"tt",
|
|
341
|
+
// Tatar
|
|
342
|
+
"te",
|
|
343
|
+
// Telugu
|
|
344
|
+
"th",
|
|
345
|
+
// Thai
|
|
346
|
+
"ti",
|
|
347
|
+
// Tigrinya
|
|
348
|
+
"ts",
|
|
349
|
+
// Tsonga
|
|
101
350
|
"tr",
|
|
102
351
|
// Turkish
|
|
103
|
-
"
|
|
104
|
-
//
|
|
105
|
-
"
|
|
106
|
-
//
|
|
107
|
-
"
|
|
108
|
-
//
|
|
109
|
-
"
|
|
110
|
-
//
|
|
352
|
+
"tk",
|
|
353
|
+
// Turkmen
|
|
354
|
+
"ak",
|
|
355
|
+
// Twi
|
|
356
|
+
"uk",
|
|
357
|
+
// Ukrainian
|
|
358
|
+
"ur",
|
|
359
|
+
// Urdu
|
|
360
|
+
"ug",
|
|
361
|
+
// Uyghur
|
|
362
|
+
"uz",
|
|
363
|
+
// Uzbek
|
|
364
|
+
"vi",
|
|
365
|
+
// Vietnamese
|
|
366
|
+
"cy",
|
|
367
|
+
// Welsh
|
|
368
|
+
"xh",
|
|
369
|
+
// Xhosa
|
|
370
|
+
"yi",
|
|
371
|
+
// Yiddish
|
|
372
|
+
"yo",
|
|
373
|
+
// Yoruba
|
|
374
|
+
"zu"
|
|
375
|
+
// Zulu
|
|
111
376
|
];
|
|
112
377
|
TRANSLATION_CONFIG_SCHEMA = {
|
|
113
378
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
@@ -148,83 +413,33 @@ var init_schema = __esm({
|
|
|
148
413
|
}
|
|
149
414
|
});
|
|
150
415
|
|
|
151
|
-
// src/translations/
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const langPath = path.join(translationsPath, language);
|
|
156
|
-
if (!fs.existsSync(langPath)) {
|
|
157
|
-
return {};
|
|
158
|
-
}
|
|
159
|
-
const files = fs.readdirSync(langPath).filter((f) => f.endsWith(".json"));
|
|
160
|
-
const translations = {};
|
|
161
|
-
for (const file of files) {
|
|
162
|
-
const namespace = path.basename(file, ".json");
|
|
163
|
-
const filePath = path.join(langPath, file);
|
|
164
|
-
const content = fs.readFileSync(filePath, "utf-8");
|
|
165
|
-
translations[namespace] = JSON.parse(content);
|
|
166
|
-
}
|
|
167
|
-
return translations;
|
|
168
|
-
}
|
|
169
|
-
function writeTranslation(translationsPath, language, namespace, translations) {
|
|
170
|
-
const langPath = path.join(translationsPath, language);
|
|
171
|
-
if (!fs.existsSync(langPath)) {
|
|
172
|
-
fs.mkdirSync(langPath, { recursive: true });
|
|
173
|
-
}
|
|
174
|
-
const filePath = path.join(langPath, `${namespace}.json`);
|
|
175
|
-
fs.writeFileSync(filePath, JSON.stringify(translations, null, 2) + "\n", "utf-8");
|
|
176
|
-
}
|
|
177
|
-
function getAvailableLanguages(translationsPath) {
|
|
178
|
-
if (!fs.existsSync(translationsPath)) {
|
|
179
|
-
return [];
|
|
180
|
-
}
|
|
181
|
-
return fs.readdirSync(translationsPath, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
182
|
-
}
|
|
183
|
-
function getNamespaces(translationsPath, language) {
|
|
184
|
-
const langPath = path.join(translationsPath, language);
|
|
185
|
-
if (!fs.existsSync(langPath)) {
|
|
186
|
-
return [];
|
|
187
|
-
}
|
|
188
|
-
return fs.readdirSync(langPath).filter((f) => f.endsWith(".json")).map((f) => path.basename(f, ".json"));
|
|
189
|
-
}
|
|
190
|
-
function hasInterpolation(text) {
|
|
191
|
-
return /\{\{[^}]+\}\}/g.test(text);
|
|
192
|
-
}
|
|
193
|
-
function extractVariables(text) {
|
|
194
|
-
const matches = text.match(/\{\{([^}]+)\}\}/g);
|
|
195
|
-
if (!matches) return [];
|
|
196
|
-
return matches.map((match) => match.replace(/\{\{|\}\}/g, "").trim());
|
|
197
|
-
}
|
|
198
|
-
function validateVariables(sourceText, translatedText) {
|
|
199
|
-
const sourceVars = extractVariables(sourceText).sort();
|
|
200
|
-
const translatedVars = extractVariables(translatedText).sort();
|
|
201
|
-
if (sourceVars.length !== translatedVars.length) {
|
|
202
|
-
return false;
|
|
203
|
-
}
|
|
204
|
-
return sourceVars.every((v, i) => v === translatedVars[i]);
|
|
205
|
-
}
|
|
206
|
-
function sortKeys(obj) {
|
|
207
|
-
const sorted = {};
|
|
208
|
-
const keys = Object.keys(obj).sort();
|
|
209
|
-
for (const key of keys) {
|
|
210
|
-
sorted[key] = obj[key];
|
|
211
|
-
}
|
|
212
|
-
return sorted;
|
|
213
|
-
}
|
|
214
|
-
function ensureTranslationsStructure(translationsPath, languages) {
|
|
215
|
-
if (!fs.existsSync(translationsPath)) {
|
|
216
|
-
fs.mkdirSync(translationsPath, { recursive: true });
|
|
217
|
-
}
|
|
218
|
-
for (const lang of languages) {
|
|
219
|
-
const langPath = path.join(translationsPath, lang);
|
|
220
|
-
if (!fs.existsSync(langPath)) {
|
|
221
|
-
fs.mkdirSync(langPath, { recursive: true });
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
var init_utils = __esm({
|
|
226
|
-
"src/translations/utils/utils.ts"() {
|
|
416
|
+
// src/translations/core/types.ts
|
|
417
|
+
var DEFAULT_CONFIG, DEFAULT_LANGUAGES;
|
|
418
|
+
var init_types = __esm({
|
|
419
|
+
"src/translations/core/types.ts"() {
|
|
227
420
|
"use strict";
|
|
421
|
+
DEFAULT_CONFIG = {
|
|
422
|
+
translationsPath: "public/static/locales",
|
|
423
|
+
languages: ["en"],
|
|
424
|
+
sourceLanguage: "en",
|
|
425
|
+
typesOutputPath: "src/types/i18nTypes.ts"
|
|
426
|
+
};
|
|
427
|
+
DEFAULT_LANGUAGES = [
|
|
428
|
+
"en",
|
|
429
|
+
"fr",
|
|
430
|
+
"it",
|
|
431
|
+
"pl",
|
|
432
|
+
"es",
|
|
433
|
+
"pt",
|
|
434
|
+
"de",
|
|
435
|
+
"de_at",
|
|
436
|
+
"nl",
|
|
437
|
+
"sv",
|
|
438
|
+
"hu",
|
|
439
|
+
"cs",
|
|
440
|
+
"ja",
|
|
441
|
+
"zh_hk"
|
|
442
|
+
];
|
|
228
443
|
}
|
|
229
444
|
});
|
|
230
445
|
|
|
@@ -294,7 +509,8 @@ function initTranslations(projectRoot, config = {}) {
|
|
|
294
509
|
ERROR: "Error",
|
|
295
510
|
SUCCESS: "Success"
|
|
296
511
|
};
|
|
297
|
-
fs2.writeFileSync(commonPath, JSON.stringify(sampleTranslations, null, 2)
|
|
512
|
+
fs2.writeFileSync(commonPath, `${JSON.stringify(sampleTranslations, null, 2)}
|
|
513
|
+
`, "utf-8");
|
|
298
514
|
console.log(`Created sample file: ${commonPath}`);
|
|
299
515
|
}
|
|
300
516
|
for (const lang of languages) {
|
|
@@ -314,7 +530,8 @@ function initTranslations(projectRoot, config = {}) {
|
|
|
314
530
|
sourceLanguage,
|
|
315
531
|
typesOutputPath: finalConfig.typesOutputPath
|
|
316
532
|
};
|
|
317
|
-
fs2.writeFileSync(configPath, JSON.stringify(configContent, null, 2)
|
|
533
|
+
fs2.writeFileSync(configPath, `${JSON.stringify(configContent, null, 2)}
|
|
534
|
+
`, "utf-8");
|
|
318
535
|
console.log(`Created config file: ${configPath}`);
|
|
319
536
|
}
|
|
320
537
|
console.log("=====");
|
|
@@ -355,16 +572,11 @@ var init_init = __esm({
|
|
|
355
572
|
}
|
|
356
573
|
});
|
|
357
574
|
|
|
358
|
-
// src/translations/
|
|
359
|
-
|
|
360
|
-
init_schema();
|
|
361
|
-
init_utils();
|
|
575
|
+
// src/translations/cli/add-key.ts
|
|
576
|
+
import * as path3 from "path";
|
|
362
577
|
|
|
363
|
-
// src/translations/utils/
|
|
364
|
-
|
|
365
|
-
if (!apiKey) {
|
|
366
|
-
throw new Error("Google Translate API key is required. Set GOOGLE_TRANSLATE_API_KEY environment variable.");
|
|
367
|
-
}
|
|
578
|
+
// src/translations/utils/google-translate-provider.ts
|
|
579
|
+
function preserveVariables(text) {
|
|
368
580
|
const variableMap = /* @__PURE__ */ new Map();
|
|
369
581
|
let placeholderIndex = 0;
|
|
370
582
|
const textWithPlaceholders = text.replace(/\{\{([^}]+)\}\}/g, (match) => {
|
|
@@ -373,209 +585,99 @@ async function translateText(text, targetLang, sourceLang = "en", apiKey) {
|
|
|
373
585
|
placeholderIndex++;
|
|
374
586
|
return placeholder;
|
|
375
587
|
});
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
"Content-Type": "application/json"
|
|
381
|
-
},
|
|
382
|
-
body: JSON.stringify({
|
|
383
|
-
q: textWithPlaceholders,
|
|
384
|
-
source: sourceLang,
|
|
385
|
-
target: targetLang.split("_")[0],
|
|
386
|
-
// Convert 'pt_BR' to 'pt'
|
|
387
|
-
format: "text"
|
|
388
|
-
})
|
|
389
|
-
});
|
|
390
|
-
const data = await response.json();
|
|
391
|
-
if (data.error) {
|
|
392
|
-
throw new Error(`Google Translate API error: ${data.error.message}`);
|
|
393
|
-
}
|
|
394
|
-
let translatedText = data.data.translations[0].translatedText;
|
|
588
|
+
return { textWithPlaceholders, variableMap };
|
|
589
|
+
}
|
|
590
|
+
function restoreVariables(text, variableMap) {
|
|
591
|
+
let result = text;
|
|
395
592
|
for (const [placeholder, original] of variableMap) {
|
|
396
|
-
|
|
593
|
+
result = result.replace(new RegExp(placeholder, "g"), original);
|
|
397
594
|
}
|
|
398
|
-
return
|
|
595
|
+
return result;
|
|
399
596
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
597
|
+
var GoogleTranslateProvider = class {
|
|
598
|
+
async translate(options) {
|
|
599
|
+
const { text, sourceLang, targetLang, apiKey } = options;
|
|
600
|
+
if (!apiKey) {
|
|
601
|
+
throw new Error(
|
|
602
|
+
"Google Translate API key is required. Set GOOGLE_TRANSLATE_API_KEY environment variable or provide apiKey in options."
|
|
603
|
+
);
|
|
407
604
|
}
|
|
605
|
+
const { textWithPlaceholders, variableMap } = preserveVariables(text);
|
|
606
|
+
const url = `https://translation.googleapis.com/language/translate/v2?key=${apiKey}`;
|
|
607
|
+
const response = await fetch(url, {
|
|
608
|
+
method: "POST",
|
|
609
|
+
headers: {
|
|
610
|
+
"Content-Type": "application/json"
|
|
611
|
+
},
|
|
612
|
+
body: JSON.stringify({
|
|
613
|
+
q: textWithPlaceholders,
|
|
614
|
+
source: sourceLang,
|
|
615
|
+
target: targetLang.split("_")[0],
|
|
616
|
+
// Convert 'pt_BR' to 'pt'
|
|
617
|
+
format: "text"
|
|
618
|
+
})
|
|
619
|
+
});
|
|
620
|
+
const data = await response.json();
|
|
621
|
+
if (data.error) {
|
|
622
|
+
throw new Error(`Google Translate API error: ${data.error.message}`);
|
|
623
|
+
}
|
|
624
|
+
const translatedText = data.data.translations[0].translatedText;
|
|
625
|
+
return restoreVariables(translatedText, variableMap);
|
|
408
626
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
const { detectExistingTranslations: detectExistingTranslations2 } = await Promise.resolve().then(() => (init_init(), init_exports));
|
|
437
|
-
const existing = detectExistingTranslations2(projectRoot);
|
|
438
|
-
let translationsPath;
|
|
439
|
-
let languages;
|
|
440
|
-
if (existing.path) {
|
|
441
|
-
console.log(`\u2713 Found existing translations at: ${existing.path}`);
|
|
442
|
-
const useExisting = await confirm({
|
|
443
|
-
message: "Use this location?",
|
|
444
|
-
default: true
|
|
445
|
-
});
|
|
446
|
-
if (useExisting) {
|
|
447
|
-
translationsPath = existing.path;
|
|
448
|
-
} else {
|
|
449
|
-
translationsPath = await input({
|
|
450
|
-
message: "Enter translations directory path:",
|
|
451
|
-
default: DEFAULT_CONFIG.translationsPath,
|
|
452
|
-
validate: (value) => {
|
|
453
|
-
if (!value.trim()) return "Path is required";
|
|
454
|
-
return true;
|
|
455
|
-
}
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
} else {
|
|
459
|
-
translationsPath = await input({
|
|
460
|
-
message: "Where should translations be stored?",
|
|
461
|
-
default: DEFAULT_CONFIG.translationsPath,
|
|
462
|
-
validate: (value) => {
|
|
463
|
-
if (!value.trim()) return "Path is required";
|
|
464
|
-
return true;
|
|
465
|
-
}
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
if (existing.languages.length > 0) {
|
|
469
|
-
console.log(`\u2713 Found existing languages: ${existing.languages.join(", ")}`);
|
|
470
|
-
const useExistingLangs = await confirm({
|
|
471
|
-
message: "Use these languages?",
|
|
472
|
-
default: true
|
|
473
|
-
});
|
|
474
|
-
if (useExistingLangs) {
|
|
475
|
-
languages = existing.languages;
|
|
476
|
-
} else {
|
|
477
|
-
languages = await selectLanguages();
|
|
478
|
-
}
|
|
479
|
-
} else {
|
|
480
|
-
languages = await selectLanguages();
|
|
481
|
-
}
|
|
482
|
-
const sourceLanguage = await input({
|
|
483
|
-
message: "What is your source language?",
|
|
484
|
-
default: "en",
|
|
485
|
-
validate: (value) => {
|
|
486
|
-
if (!SUPPORTED_LANGUAGES.includes(value)) {
|
|
487
|
-
return `Invalid language code. Must be one of: ${SUPPORTED_LANGUAGES.join(", ")}`;
|
|
488
|
-
}
|
|
489
|
-
if (!languages.includes(value)) {
|
|
490
|
-
return "Source language must be in the list of supported languages";
|
|
491
|
-
}
|
|
492
|
-
return true;
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
const typesOutputPath = await input({
|
|
496
|
-
message: "Where should TypeScript types be generated?",
|
|
497
|
-
default: DEFAULT_CONFIG.typesOutputPath
|
|
498
|
-
});
|
|
499
|
-
console.log("\n\u{1F4CB} Configuration Summary:");
|
|
500
|
-
console.log(` Translations: ${translationsPath}`);
|
|
501
|
-
console.log(` Languages: ${languages.join(", ")}`);
|
|
502
|
-
console.log(` Source: ${sourceLanguage}`);
|
|
503
|
-
console.log(` Types: ${typesOutputPath}`);
|
|
504
|
-
const confirmInit = await confirm({
|
|
505
|
-
message: "\nProceed with initialization?",
|
|
506
|
-
default: true
|
|
507
|
-
});
|
|
508
|
-
if (!confirmInit) {
|
|
509
|
-
console.log("\u274C Cancelled");
|
|
510
|
-
return;
|
|
511
|
-
}
|
|
512
|
-
const config = {
|
|
513
|
-
translationsPath,
|
|
514
|
-
languages,
|
|
515
|
-
sourceLanguage,
|
|
516
|
-
typesOutputPath
|
|
517
|
-
};
|
|
518
|
-
console.log();
|
|
519
|
-
initTranslations(projectRoot, config);
|
|
520
|
-
console.log("\n\u{1F4DD} Configuration saved to: .translationsrc.json");
|
|
521
|
-
console.log("\n\u{1F4A1} Next steps:");
|
|
522
|
-
console.log(' 1. Run "translations add" to add your first translation key');
|
|
523
|
-
console.log(' 2. Run "translations" to validate and generate types');
|
|
524
|
-
console.log(" 3. Check the .translationsrc.json file for your configuration\n");
|
|
627
|
+
async translateBatch(texts, sourceLang, targetLang, apiKey, delayMs = 100) {
|
|
628
|
+
const results = [];
|
|
629
|
+
for (const text of texts) {
|
|
630
|
+
const translated = await this.translate({
|
|
631
|
+
text,
|
|
632
|
+
sourceLang,
|
|
633
|
+
targetLang,
|
|
634
|
+
apiKey
|
|
635
|
+
});
|
|
636
|
+
results.push(translated);
|
|
637
|
+
if (delayMs > 0) {
|
|
638
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return results;
|
|
642
|
+
}
|
|
643
|
+
async validateConfig() {
|
|
644
|
+
const apiKey = process.env.GOOGLE_TRANSLATE_API_KEY;
|
|
645
|
+
return !!apiKey;
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
// src/translations/utils/translator.ts
|
|
650
|
+
var defaultProvider = new GoogleTranslateProvider();
|
|
651
|
+
var customProvider = null;
|
|
652
|
+
function setTranslationProvider(provider) {
|
|
653
|
+
customProvider = provider;
|
|
525
654
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
const
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
655
|
+
function getTranslationProvider() {
|
|
656
|
+
return customProvider || defaultProvider;
|
|
657
|
+
}
|
|
658
|
+
function resetTranslationProvider() {
|
|
659
|
+
customProvider = null;
|
|
660
|
+
}
|
|
661
|
+
async function translateText(text, targetLang, sourceLang = "en", apiKey) {
|
|
662
|
+
const provider = getTranslationProvider();
|
|
663
|
+
return provider.translate({
|
|
664
|
+
text,
|
|
665
|
+
sourceLang,
|
|
666
|
+
targetLang,
|
|
667
|
+
apiKey
|
|
539
668
|
});
|
|
540
|
-
return selected;
|
|
541
669
|
}
|
|
542
|
-
function
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
fr: "French",
|
|
546
|
-
it: "Italian",
|
|
547
|
-
pl: "Polish",
|
|
548
|
-
es: "Spanish",
|
|
549
|
-
pt: "Portuguese",
|
|
550
|
-
de: "German",
|
|
551
|
-
de_at: "German (Austria)",
|
|
552
|
-
nl: "Dutch",
|
|
553
|
-
sv: "Swedish",
|
|
554
|
-
hu: "Hungarian",
|
|
555
|
-
cs: "Czech",
|
|
556
|
-
ja: "Japanese",
|
|
557
|
-
zh_hk: "Chinese (Hong Kong)",
|
|
558
|
-
zh_cn: "Chinese (Simplified)",
|
|
559
|
-
ko: "Korean",
|
|
560
|
-
ru: "Russian",
|
|
561
|
-
ar: "Arabic",
|
|
562
|
-
he: "Hebrew",
|
|
563
|
-
tr: "Turkish",
|
|
564
|
-
da: "Danish",
|
|
565
|
-
fi: "Finnish",
|
|
566
|
-
no: "Norwegian",
|
|
567
|
-
pt_br: "Portuguese (Brazil)"
|
|
568
|
-
};
|
|
569
|
-
return names[code] || code;
|
|
670
|
+
async function translateBatch(texts, targetLang, sourceLang = "en", apiKey, delayMs = 100) {
|
|
671
|
+
const provider = getTranslationProvider();
|
|
672
|
+
return provider.translateBatch(texts, sourceLang, targetLang, apiKey, delayMs);
|
|
570
673
|
}
|
|
571
674
|
|
|
572
675
|
// src/translations/cli/add-key.ts
|
|
573
|
-
import * as path4 from "path";
|
|
574
676
|
init_utils();
|
|
575
677
|
init_init();
|
|
576
678
|
async function addTranslationKey(projectRoot, options) {
|
|
577
679
|
const config = loadConfig(projectRoot);
|
|
578
|
-
const translationsPath =
|
|
680
|
+
const translationsPath = path3.join(projectRoot, config.translationsPath);
|
|
579
681
|
const { namespace, key, value, autoTranslate = false, apiKey } = options;
|
|
580
682
|
console.log("=====");
|
|
581
683
|
console.log("Adding translation key");
|
|
@@ -656,13 +758,18 @@ async function addTranslationKeys(projectRoot, entries, autoTranslate = false, a
|
|
|
656
758
|
}
|
|
657
759
|
}
|
|
658
760
|
|
|
761
|
+
// src/translations/cli/auto-fill.ts
|
|
762
|
+
import * as path5 from "path";
|
|
763
|
+
init_utils();
|
|
764
|
+
init_init();
|
|
765
|
+
|
|
659
766
|
// src/translations/cli/validate.ts
|
|
660
767
|
init_utils();
|
|
661
768
|
init_init();
|
|
662
|
-
import * as
|
|
769
|
+
import * as path4 from "path";
|
|
663
770
|
function validateTranslations(projectRoot = process.cwd()) {
|
|
664
771
|
const config = loadConfig(projectRoot);
|
|
665
|
-
const translationsPath =
|
|
772
|
+
const translationsPath = path4.join(projectRoot, config.translationsPath);
|
|
666
773
|
const sourceLanguage = config.sourceLanguage;
|
|
667
774
|
const missing = [];
|
|
668
775
|
const empty = [];
|
|
@@ -739,12 +846,9 @@ function getMissingForLanguage(projectRoot, language) {
|
|
|
739
846
|
}
|
|
740
847
|
|
|
741
848
|
// src/translations/cli/auto-fill.ts
|
|
742
|
-
import * as path6 from "path";
|
|
743
|
-
init_utils();
|
|
744
|
-
init_init();
|
|
745
849
|
async function autoFillTranslations(projectRoot = process.cwd(), options = {}) {
|
|
746
850
|
const config = loadConfig(projectRoot);
|
|
747
|
-
const translationsPath =
|
|
851
|
+
const translationsPath = path5.join(projectRoot, config.translationsPath);
|
|
748
852
|
const { apiKey, limit = 1e3, delayMs = 100, dryRun = false } = options;
|
|
749
853
|
if (!apiKey) {
|
|
750
854
|
throw new Error("Google Translate API key is required. Set GOOGLE_TRANSLATE_API_KEY or pass --api-key");
|
|
@@ -813,7 +917,7 @@ Processing language: ${language}`);
|
|
|
813
917
|
}
|
|
814
918
|
async function fillNamespace(projectRoot, language, namespace, apiKey) {
|
|
815
919
|
const config = loadConfig(projectRoot);
|
|
816
|
-
const translationsPath =
|
|
920
|
+
const translationsPath = path5.join(projectRoot, config.translationsPath);
|
|
817
921
|
console.log(`Filling translations for ${language}/${namespace}.json`);
|
|
818
922
|
const sourceTranslations = readTranslations(translationsPath, config.sourceLanguage);
|
|
819
923
|
const targetTranslations = readTranslations(translationsPath, language);
|
|
@@ -845,7 +949,7 @@ init_utils();
|
|
|
845
949
|
init_init();
|
|
846
950
|
import { execSync } from "child_process";
|
|
847
951
|
import * as fs3 from "fs";
|
|
848
|
-
import * as
|
|
952
|
+
import * as path6 from "path";
|
|
849
953
|
var typeTemplate = (translationKeys, namespaceKeys) => `
|
|
850
954
|
export const translationKeys = [${translationKeys.map((key) => `"${key}"`).join(", ")}] as const;
|
|
851
955
|
export const namespaceKeys = [${namespaceKeys.map((key) => `"${key}"`).join(", ")}] as const;
|
|
@@ -859,10 +963,10 @@ function generateTranslationTypes(projectRoot = process.cwd()) {
|
|
|
859
963
|
console.log("Generating i18n types");
|
|
860
964
|
console.log("=====");
|
|
861
965
|
const config = loadConfig(projectRoot);
|
|
862
|
-
const translationsPath =
|
|
966
|
+
const translationsPath = path6.join(projectRoot, config.translationsPath);
|
|
863
967
|
const sourceLanguage = config.sourceLanguage;
|
|
864
|
-
const outputFilePath =
|
|
865
|
-
const dirPath =
|
|
968
|
+
const outputFilePath = path6.join(projectRoot, config.typesOutputPath);
|
|
969
|
+
const dirPath = path6.join(translationsPath, sourceLanguage);
|
|
866
970
|
if (!fs3.existsSync(dirPath)) {
|
|
867
971
|
throw new Error(`Source language directory not found: ${dirPath}`);
|
|
868
972
|
}
|
|
@@ -876,7 +980,7 @@ function generateTranslationTypes(projectRoot = process.cwd()) {
|
|
|
876
980
|
const keys = Object.keys(translations[namespace] || {});
|
|
877
981
|
allKeys = allKeys.concat(keys);
|
|
878
982
|
}
|
|
879
|
-
const outputDir =
|
|
983
|
+
const outputDir = path6.dirname(outputFilePath);
|
|
880
984
|
if (!fs3.existsSync(outputDir)) {
|
|
881
985
|
fs3.mkdirSync(outputDir, { recursive: true });
|
|
882
986
|
}
|
|
@@ -885,7 +989,10 @@ function generateTranslationTypes(projectRoot = process.cwd()) {
|
|
|
885
989
|
console.log(`Generated types with ${allKeys.length} keys and ${namespaces.length} namespaces`);
|
|
886
990
|
console.log(`Output: ${outputFilePath}`);
|
|
887
991
|
try {
|
|
888
|
-
execSync(`pnpm biome format --write ${outputFilePath}`, {
|
|
992
|
+
execSync(`pnpm biome format --write ${outputFilePath}`, {
|
|
993
|
+
stdio: "inherit",
|
|
994
|
+
cwd: projectRoot
|
|
995
|
+
});
|
|
889
996
|
} catch {
|
|
890
997
|
console.warn("Failed to format with Biome, continuing without formatting...");
|
|
891
998
|
}
|
|
@@ -893,8 +1000,169 @@ function generateTranslationTypes(projectRoot = process.cwd()) {
|
|
|
893
1000
|
console.log("=====");
|
|
894
1001
|
}
|
|
895
1002
|
|
|
896
|
-
// src/translations/
|
|
1003
|
+
// src/translations/index.ts
|
|
1004
|
+
init_init();
|
|
1005
|
+
|
|
1006
|
+
// src/translations/cli/init-interactive.ts
|
|
1007
|
+
init_schema();
|
|
1008
|
+
init_types();
|
|
1009
|
+
init_init();
|
|
897
1010
|
import * as fs4 from "fs";
|
|
1011
|
+
import * as path7 from "path";
|
|
1012
|
+
import { checkbox, confirm, input } from "@inquirer/prompts";
|
|
1013
|
+
async function initTranslationsInteractive(projectRoot = process.cwd()) {
|
|
1014
|
+
console.log("\n\u{1F30D} Translation System Setup\n");
|
|
1015
|
+
const configPath = path7.join(projectRoot, ".translationsrc.json");
|
|
1016
|
+
const alreadyExists = fs4.existsSync(configPath);
|
|
1017
|
+
if (alreadyExists) {
|
|
1018
|
+
console.log("\u26A0\uFE0F Configuration file already exists at .translationsrc.json\n");
|
|
1019
|
+
const shouldOverwrite = await confirm({
|
|
1020
|
+
message: "Would you like to reconfigure?",
|
|
1021
|
+
default: false
|
|
1022
|
+
});
|
|
1023
|
+
if (!shouldOverwrite) {
|
|
1024
|
+
console.log("\u2713 Keeping existing configuration");
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
const { detectExistingTranslations: detectExistingTranslations2 } = await Promise.resolve().then(() => (init_init(), init_exports));
|
|
1029
|
+
const existing = detectExistingTranslations2(projectRoot);
|
|
1030
|
+
let translationsPath;
|
|
1031
|
+
let languages;
|
|
1032
|
+
if (existing.path) {
|
|
1033
|
+
console.log(`\u2713 Found existing translations at: ${existing.path}`);
|
|
1034
|
+
const useExisting = await confirm({
|
|
1035
|
+
message: "Use this location?",
|
|
1036
|
+
default: true
|
|
1037
|
+
});
|
|
1038
|
+
if (useExisting) {
|
|
1039
|
+
translationsPath = existing.path;
|
|
1040
|
+
} else {
|
|
1041
|
+
translationsPath = await input({
|
|
1042
|
+
message: "Enter translations directory path:",
|
|
1043
|
+
default: DEFAULT_CONFIG.translationsPath,
|
|
1044
|
+
validate: (value) => {
|
|
1045
|
+
if (!value.trim()) return "Path is required";
|
|
1046
|
+
return true;
|
|
1047
|
+
}
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
} else {
|
|
1051
|
+
translationsPath = await input({
|
|
1052
|
+
message: "Where should translations be stored?",
|
|
1053
|
+
default: DEFAULT_CONFIG.translationsPath,
|
|
1054
|
+
validate: (value) => {
|
|
1055
|
+
if (!value.trim()) return "Path is required";
|
|
1056
|
+
return true;
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
if (existing.languages.length > 0) {
|
|
1061
|
+
console.log(`\u2713 Found existing languages: ${existing.languages.join(", ")}`);
|
|
1062
|
+
const useExistingLangs = await confirm({
|
|
1063
|
+
message: "Use these languages?",
|
|
1064
|
+
default: true
|
|
1065
|
+
});
|
|
1066
|
+
if (useExistingLangs) {
|
|
1067
|
+
languages = existing.languages;
|
|
1068
|
+
} else {
|
|
1069
|
+
languages = await selectLanguages();
|
|
1070
|
+
}
|
|
1071
|
+
} else {
|
|
1072
|
+
languages = await selectLanguages();
|
|
1073
|
+
}
|
|
1074
|
+
const sourceLanguage = await input({
|
|
1075
|
+
message: "What is your source language?",
|
|
1076
|
+
default: "en",
|
|
1077
|
+
validate: (value) => {
|
|
1078
|
+
if (!SUPPORTED_LANGUAGES.includes(value)) {
|
|
1079
|
+
return `Invalid language code. Must be one of: ${SUPPORTED_LANGUAGES.join(", ")}`;
|
|
1080
|
+
}
|
|
1081
|
+
if (!languages.includes(value)) {
|
|
1082
|
+
return "Source language must be in the list of supported languages";
|
|
1083
|
+
}
|
|
1084
|
+
return true;
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
const typesOutputPath = await input({
|
|
1088
|
+
message: "Where should TypeScript types be generated?",
|
|
1089
|
+
default: DEFAULT_CONFIG.typesOutputPath
|
|
1090
|
+
});
|
|
1091
|
+
console.log("\n\u{1F4CB} Configuration Summary:");
|
|
1092
|
+
console.log(` Translations: ${translationsPath}`);
|
|
1093
|
+
console.log(` Languages: ${languages.join(", ")}`);
|
|
1094
|
+
console.log(` Source: ${sourceLanguage}`);
|
|
1095
|
+
console.log(` Types: ${typesOutputPath}`);
|
|
1096
|
+
const confirmInit = await confirm({
|
|
1097
|
+
message: "\nProceed with initialization?",
|
|
1098
|
+
default: true
|
|
1099
|
+
});
|
|
1100
|
+
if (!confirmInit) {
|
|
1101
|
+
console.log("\u274C Cancelled");
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1104
|
+
const config = {
|
|
1105
|
+
translationsPath,
|
|
1106
|
+
languages,
|
|
1107
|
+
sourceLanguage,
|
|
1108
|
+
typesOutputPath
|
|
1109
|
+
};
|
|
1110
|
+
console.log();
|
|
1111
|
+
initTranslations(projectRoot, config);
|
|
1112
|
+
console.log("\n\u{1F4DD} Configuration saved to: .translationsrc.json");
|
|
1113
|
+
console.log("\n\u{1F4A1} Next steps:");
|
|
1114
|
+
console.log(' 1. Run "translations add" to add your first translation key');
|
|
1115
|
+
console.log(' 2. Run "translations" to validate and generate types');
|
|
1116
|
+
console.log(" 3. Check the .translationsrc.json file for your configuration\n");
|
|
1117
|
+
}
|
|
1118
|
+
async function selectLanguages() {
|
|
1119
|
+
const languageChoices = SUPPORTED_LANGUAGES.map((lang) => ({
|
|
1120
|
+
name: `${lang} - ${getLanguageName(lang)}`,
|
|
1121
|
+
value: lang,
|
|
1122
|
+
checked: lang === "en"
|
|
1123
|
+
// English selected by default
|
|
1124
|
+
}));
|
|
1125
|
+
const selected = await checkbox({
|
|
1126
|
+
message: "Select languages to support (space to select, enter to confirm):",
|
|
1127
|
+
choices: languageChoices,
|
|
1128
|
+
required: true,
|
|
1129
|
+
pageSize: 15,
|
|
1130
|
+
loop: false
|
|
1131
|
+
});
|
|
1132
|
+
return selected;
|
|
1133
|
+
}
|
|
1134
|
+
function getLanguageName(code) {
|
|
1135
|
+
const names = {
|
|
1136
|
+
en: "English",
|
|
1137
|
+
fr: "French",
|
|
1138
|
+
it: "Italian",
|
|
1139
|
+
pl: "Polish",
|
|
1140
|
+
es: "Spanish",
|
|
1141
|
+
pt: "Portuguese",
|
|
1142
|
+
de: "German",
|
|
1143
|
+
de_at: "German (Austria)",
|
|
1144
|
+
nl: "Dutch",
|
|
1145
|
+
sv: "Swedish",
|
|
1146
|
+
hu: "Hungarian",
|
|
1147
|
+
cs: "Czech",
|
|
1148
|
+
ja: "Japanese",
|
|
1149
|
+
zh_hk: "Chinese (Hong Kong)",
|
|
1150
|
+
zh_cn: "Chinese (Simplified)",
|
|
1151
|
+
ko: "Korean",
|
|
1152
|
+
ru: "Russian",
|
|
1153
|
+
ar: "Arabic",
|
|
1154
|
+
he: "Hebrew",
|
|
1155
|
+
tr: "Turkish",
|
|
1156
|
+
da: "Danish",
|
|
1157
|
+
fi: "Finnish",
|
|
1158
|
+
no: "Norwegian",
|
|
1159
|
+
pt_br: "Portuguese (Brazil)"
|
|
1160
|
+
};
|
|
1161
|
+
return names[code] || code;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
// src/translations/cli/manage.ts
|
|
1165
|
+
import * as fs5 from "fs";
|
|
898
1166
|
import * as path8 from "path";
|
|
899
1167
|
init_init();
|
|
900
1168
|
async function manageTranslations(projectRoot = process.cwd(), options = {}) {
|
|
@@ -903,7 +1171,7 @@ async function manageTranslations(projectRoot = process.cwd(), options = {}) {
|
|
|
903
1171
|
console.log("Translation Management");
|
|
904
1172
|
console.log("=====");
|
|
905
1173
|
const configPath = path8.join(projectRoot, ".translationsrc.json");
|
|
906
|
-
const isInitialized =
|
|
1174
|
+
const isInitialized = fs5.existsSync(configPath);
|
|
907
1175
|
if (!isInitialized) {
|
|
908
1176
|
console.log("\u{1F4C1} No translation configuration found. Initializing...\n");
|
|
909
1177
|
initTranslations(projectRoot);
|
|
@@ -914,7 +1182,7 @@ async function manageTranslations(projectRoot = process.cwd(), options = {}) {
|
|
|
914
1182
|
const config = loadConfig(projectRoot);
|
|
915
1183
|
const translationsPath = path8.join(projectRoot, config.translationsPath);
|
|
916
1184
|
const sourceLangPath = path8.join(translationsPath, config.sourceLanguage);
|
|
917
|
-
if (!
|
|
1185
|
+
if (!fs5.existsSync(sourceLangPath)) {
|
|
918
1186
|
console.log(`\u26A0\uFE0F Source language directory not found: ${sourceLangPath}`);
|
|
919
1187
|
console.log("Please add translation files to the source language directory.\n");
|
|
920
1188
|
return;
|
|
@@ -982,9 +1250,15 @@ async function manageTranslations(projectRoot = process.cwd(), options = {}) {
|
|
|
982
1250
|
}
|
|
983
1251
|
console.log("=====\n");
|
|
984
1252
|
}
|
|
1253
|
+
|
|
1254
|
+
// src/translations/index.ts
|
|
1255
|
+
init_schema();
|
|
1256
|
+
init_types();
|
|
1257
|
+
init_utils();
|
|
985
1258
|
export {
|
|
986
1259
|
DEFAULT_CONFIG,
|
|
987
1260
|
DEFAULT_LANGUAGES,
|
|
1261
|
+
GoogleTranslateProvider,
|
|
988
1262
|
SUPPORTED_LANGUAGES,
|
|
989
1263
|
TRANSLATION_CONFIG_SCHEMA,
|
|
990
1264
|
addTranslationKey,
|
|
@@ -998,6 +1272,7 @@ export {
|
|
|
998
1272
|
getAvailableLanguages,
|
|
999
1273
|
getMissingForLanguage,
|
|
1000
1274
|
getNamespaces,
|
|
1275
|
+
getTranslationProvider,
|
|
1001
1276
|
hasInterpolation,
|
|
1002
1277
|
initTranslations,
|
|
1003
1278
|
initTranslationsInteractive,
|
|
@@ -1005,6 +1280,8 @@ export {
|
|
|
1005
1280
|
loadConfig,
|
|
1006
1281
|
manageTranslations,
|
|
1007
1282
|
readTranslations,
|
|
1283
|
+
resetTranslationProvider,
|
|
1284
|
+
setTranslationProvider,
|
|
1008
1285
|
sortKeys,
|
|
1009
1286
|
translateBatch,
|
|
1010
1287
|
translateText,
|