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