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/README.md
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
#
|
|
1
|
+
# poly-lexis
|
|
2
2
|
|
|
3
3
|
A powerful CLI and library for managing i18n translations with validation, auto-translation, and TypeScript type generation.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
poly-lexis provides a complete solution for managing internationalization (i18n) in your applications. It offers smart translation management with automatic validation, Google Translate integration for auto-filling missing translations, and TypeScript type generation for type-safe translations.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npm install lexis
|
|
12
|
+
npm install poly-lexis
|
|
13
13
|
# or
|
|
14
|
-
yarn add lexis
|
|
14
|
+
yarn add poly-lexis
|
|
15
15
|
# or
|
|
16
|
-
pnpm add lexis
|
|
16
|
+
pnpm add poly-lexis
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Quick Start
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
22
|
# Initialize translations in your project
|
|
23
|
-
npx lexis
|
|
23
|
+
npx poly-lexis
|
|
24
24
|
|
|
25
25
|
# Add a new translation key
|
|
26
|
-
npx lexis add
|
|
26
|
+
npx poly-lexis add
|
|
27
27
|
|
|
28
28
|
# Auto-fill missing translations
|
|
29
29
|
export GOOGLE_TRANSLATE_API_KEY=your_key
|
|
30
|
-
npx lexis --auto-fill
|
|
30
|
+
npx poly-lexis --auto-fill
|
|
31
31
|
|
|
32
32
|
# Validate and generate types
|
|
33
|
-
npx lexis
|
|
33
|
+
npx poly-lexis
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## Features
|
|
@@ -51,32 +51,32 @@ Run without any command to validate, auto-fill (optional), and generate types:
|
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
53
|
# Basic validation and type generation
|
|
54
|
-
lexis
|
|
54
|
+
poly-lexis
|
|
55
55
|
|
|
56
56
|
# With auto-translation
|
|
57
|
-
lexis --auto-fill
|
|
57
|
+
poly-lexis --auto-fill
|
|
58
58
|
|
|
59
59
|
# Auto-fill only specific language
|
|
60
|
-
lexis --auto-fill --language fr
|
|
60
|
+
poly-lexis --auto-fill --language fr
|
|
61
61
|
|
|
62
62
|
# Dry run to preview changes
|
|
63
|
-
lexis --auto-fill --dry-run
|
|
63
|
+
poly-lexis --auto-fill --dry-run
|
|
64
64
|
|
|
65
65
|
# Skip type generation
|
|
66
|
-
lexis --skip-types
|
|
66
|
+
poly-lexis --skip-types
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
### Add Translation Keys
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
72
|
# Interactive mode
|
|
73
|
-
lexis add
|
|
73
|
+
poly-lexis add
|
|
74
74
|
|
|
75
75
|
# With flags
|
|
76
|
-
lexis add --namespace common --key HELLO --value "Hello"
|
|
76
|
+
poly-lexis add --namespace common --key HELLO --value "Hello"
|
|
77
77
|
|
|
78
78
|
# With auto-translation
|
|
79
|
-
lexis add -n common -k WELCOME -v "Welcome" --auto-fill
|
|
79
|
+
poly-lexis add -n common -k WELCOME -v "Welcome" --auto-fill
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
### CLI Options
|
|
@@ -97,7 +97,7 @@ lexis add -n common -k WELCOME -v "Welcome" --auto-fill
|
|
|
97
97
|
|
|
98
98
|
## Configuration
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
poly-lexis uses a `.translationsrc.json` file in your project root for configuration:
|
|
101
101
|
|
|
102
102
|
```json
|
|
103
103
|
{
|
|
@@ -157,12 +157,12 @@ Translation files are organized by namespace and language:
|
|
|
157
157
|
|
|
158
158
|
## Programmatic API
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
poly-lexis can be used as a library in your Node.js code:
|
|
161
161
|
|
|
162
162
|
### Initialize Translations
|
|
163
163
|
|
|
164
164
|
```typescript
|
|
165
|
-
import { initTranslationsInteractive } from 'lexis';
|
|
165
|
+
import { initTranslationsInteractive } from 'poly-lexis';
|
|
166
166
|
|
|
167
167
|
await initTranslationsInteractive(process.cwd());
|
|
168
168
|
```
|
|
@@ -170,7 +170,7 @@ await initTranslationsInteractive(process.cwd());
|
|
|
170
170
|
### Add Translation Key
|
|
171
171
|
|
|
172
172
|
```typescript
|
|
173
|
-
import { addTranslationKey } from 'lexis';
|
|
173
|
+
import { addTranslationKey } from 'poly-lexis';
|
|
174
174
|
|
|
175
175
|
await addTranslationKey(process.cwd(), {
|
|
176
176
|
namespace: 'common',
|
|
@@ -184,7 +184,7 @@ await addTranslationKey(process.cwd(), {
|
|
|
184
184
|
### Validate Translations
|
|
185
185
|
|
|
186
186
|
```typescript
|
|
187
|
-
import { validateTranslations } from 'lexis';
|
|
187
|
+
import { validateTranslations } from 'poly-lexis';
|
|
188
188
|
|
|
189
189
|
const result = await validateTranslations(
|
|
190
190
|
'/path/to/translations',
|
|
@@ -200,7 +200,7 @@ if (!result.valid) {
|
|
|
200
200
|
### Generate TypeScript Types
|
|
201
201
|
|
|
202
202
|
```typescript
|
|
203
|
-
import { generateTranslationTypes } from 'lexis';
|
|
203
|
+
import { generateTranslationTypes } from 'poly-lexis';
|
|
204
204
|
|
|
205
205
|
generateTranslationTypes(process.cwd());
|
|
206
206
|
```
|
|
@@ -208,7 +208,7 @@ generateTranslationTypes(process.cwd());
|
|
|
208
208
|
### Auto-fill Missing Translations
|
|
209
209
|
|
|
210
210
|
```typescript
|
|
211
|
-
import { autoFillTranslations } from 'lexis';
|
|
211
|
+
import { autoFillTranslations } from 'poly-lexis';
|
|
212
212
|
|
|
213
213
|
await autoFillTranslations({
|
|
214
214
|
translationsPath: '/path/to/translations',
|
package/dist/cli/translations.js
CHANGED
|
@@ -48,7 +48,8 @@ function writeTranslation(translationsPath, language, namespace, translations) {
|
|
|
48
48
|
fs.mkdirSync(langPath, { recursive: true });
|
|
49
49
|
}
|
|
50
50
|
const filePath = path2.join(langPath, `${namespace}.json`);
|
|
51
|
-
fs.writeFileSync(filePath, JSON.stringify(translations, null, 2)
|
|
51
|
+
fs.writeFileSync(filePath, `${JSON.stringify(translations, null, 2)}
|
|
52
|
+
`, "utf-8");
|
|
52
53
|
}
|
|
53
54
|
function getAvailableLanguages(translationsPath) {
|
|
54
55
|
if (!fs.existsSync(translationsPath)) {
|
|
@@ -106,54 +107,274 @@ var init_schema = __esm({
|
|
|
106
107
|
"use strict";
|
|
107
108
|
init_esm_shims();
|
|
108
109
|
SUPPORTED_LANGUAGES = [
|
|
110
|
+
"af",
|
|
111
|
+
// Afrikaans
|
|
112
|
+
"sq",
|
|
113
|
+
// Albanian
|
|
114
|
+
"am",
|
|
115
|
+
// Amharic
|
|
116
|
+
"ar",
|
|
117
|
+
// Arabic
|
|
118
|
+
"hy",
|
|
119
|
+
// Armenian
|
|
120
|
+
"as",
|
|
121
|
+
// Assamese
|
|
122
|
+
"ay",
|
|
123
|
+
// Aymara
|
|
124
|
+
"az",
|
|
125
|
+
// Azerbaijani
|
|
126
|
+
"bm",
|
|
127
|
+
// Bambara
|
|
128
|
+
"eu",
|
|
129
|
+
// Basque
|
|
130
|
+
"be",
|
|
131
|
+
// Belarusian
|
|
132
|
+
"bn",
|
|
133
|
+
// Bengali
|
|
134
|
+
"bho",
|
|
135
|
+
// Bhojpuri
|
|
136
|
+
"bs",
|
|
137
|
+
// Bosnian
|
|
138
|
+
"bg",
|
|
139
|
+
// Bulgarian
|
|
140
|
+
"ca",
|
|
141
|
+
// Catalan
|
|
142
|
+
"ceb",
|
|
143
|
+
// Cebuano
|
|
144
|
+
"ny",
|
|
145
|
+
// Chichewa
|
|
146
|
+
"zh",
|
|
147
|
+
// Chinese (Simplified) - Google uses 'zh' or 'zh-CN'
|
|
148
|
+
"zh_cn",
|
|
149
|
+
// Chinese (Simplified) - alternative format
|
|
150
|
+
"zh_tw",
|
|
151
|
+
// Chinese (Traditional)
|
|
152
|
+
"co",
|
|
153
|
+
// Corsican
|
|
154
|
+
"hr",
|
|
155
|
+
// Croatian
|
|
156
|
+
"cs",
|
|
157
|
+
// Czech
|
|
158
|
+
"da",
|
|
159
|
+
// Danish
|
|
160
|
+
"dv",
|
|
161
|
+
// Dhivehi
|
|
162
|
+
"doi",
|
|
163
|
+
// Dogri
|
|
164
|
+
"nl",
|
|
165
|
+
// Dutch
|
|
109
166
|
"en",
|
|
110
167
|
// English
|
|
168
|
+
"eo",
|
|
169
|
+
// Esperanto
|
|
170
|
+
"et",
|
|
171
|
+
// Estonian
|
|
172
|
+
"ee",
|
|
173
|
+
// Ewe
|
|
174
|
+
"tl",
|
|
175
|
+
// Filipino (Tagalog)
|
|
176
|
+
"fi",
|
|
177
|
+
// Finnish
|
|
111
178
|
"fr",
|
|
112
179
|
// French
|
|
113
|
-
"
|
|
114
|
-
//
|
|
115
|
-
"
|
|
116
|
-
//
|
|
117
|
-
"es",
|
|
118
|
-
// Spanish
|
|
119
|
-
"pt",
|
|
120
|
-
// Portuguese
|
|
180
|
+
"gl",
|
|
181
|
+
// Galician
|
|
182
|
+
"ka",
|
|
183
|
+
// Georgian
|
|
121
184
|
"de",
|
|
122
185
|
// German
|
|
123
|
-
"
|
|
124
|
-
//
|
|
125
|
-
"
|
|
126
|
-
//
|
|
127
|
-
"
|
|
128
|
-
//
|
|
186
|
+
"el",
|
|
187
|
+
// Greek
|
|
188
|
+
"gn",
|
|
189
|
+
// Guarani
|
|
190
|
+
"gu",
|
|
191
|
+
// Gujarati
|
|
192
|
+
"ht",
|
|
193
|
+
// Haitian Creole
|
|
194
|
+
"ha",
|
|
195
|
+
// Hausa
|
|
196
|
+
"haw",
|
|
197
|
+
// Hawaiian
|
|
198
|
+
"iw",
|
|
199
|
+
// Hebrew (legacy code, 'he' is preferred)
|
|
200
|
+
"he",
|
|
201
|
+
// Hebrew
|
|
202
|
+
"hi",
|
|
203
|
+
// Hindi
|
|
204
|
+
"hmn",
|
|
205
|
+
// Hmong
|
|
129
206
|
"hu",
|
|
130
207
|
// Hungarian
|
|
131
|
-
"
|
|
132
|
-
//
|
|
208
|
+
"is",
|
|
209
|
+
// Icelandic
|
|
210
|
+
"ig",
|
|
211
|
+
// Igbo
|
|
212
|
+
"ilo",
|
|
213
|
+
// Ilocano
|
|
214
|
+
"id",
|
|
215
|
+
// Indonesian
|
|
216
|
+
"ga",
|
|
217
|
+
// Irish
|
|
218
|
+
"it",
|
|
219
|
+
// Italian
|
|
133
220
|
"ja",
|
|
134
221
|
// Japanese
|
|
135
|
-
"
|
|
136
|
-
//
|
|
137
|
-
"
|
|
138
|
-
//
|
|
222
|
+
"jw",
|
|
223
|
+
// Javanese
|
|
224
|
+
"kn",
|
|
225
|
+
// Kannada
|
|
226
|
+
"kk",
|
|
227
|
+
// Kazakh
|
|
228
|
+
"km",
|
|
229
|
+
// Khmer
|
|
230
|
+
"rw",
|
|
231
|
+
// Kinyarwanda
|
|
232
|
+
"gom",
|
|
233
|
+
// Konkani
|
|
139
234
|
"ko",
|
|
140
235
|
// Korean
|
|
236
|
+
"kri",
|
|
237
|
+
// Krio
|
|
238
|
+
"ku",
|
|
239
|
+
// Kurdish (Kurmanji)
|
|
240
|
+
"ckb",
|
|
241
|
+
// Kurdish (Sorani)
|
|
242
|
+
"ky",
|
|
243
|
+
// Kyrgyz
|
|
244
|
+
"lo",
|
|
245
|
+
// Lao
|
|
246
|
+
"la",
|
|
247
|
+
// Latin
|
|
248
|
+
"lv",
|
|
249
|
+
// Latvian
|
|
250
|
+
"ln",
|
|
251
|
+
// Lingala
|
|
252
|
+
"lt",
|
|
253
|
+
// Lithuanian
|
|
254
|
+
"lg",
|
|
255
|
+
// Luganda
|
|
256
|
+
"lb",
|
|
257
|
+
// Luxembourgish
|
|
258
|
+
"mk",
|
|
259
|
+
// Macedonian
|
|
260
|
+
"mai",
|
|
261
|
+
// Maithili
|
|
262
|
+
"mg",
|
|
263
|
+
// Malagasy
|
|
264
|
+
"ms",
|
|
265
|
+
// Malay
|
|
266
|
+
"ml",
|
|
267
|
+
// Malayalam
|
|
268
|
+
"mt",
|
|
269
|
+
// Maltese
|
|
270
|
+
"mi",
|
|
271
|
+
// Maori
|
|
272
|
+
"mr",
|
|
273
|
+
// Marathi
|
|
274
|
+
"mni",
|
|
275
|
+
// Meiteilon (Manipuri)
|
|
276
|
+
"lus",
|
|
277
|
+
// Mizo
|
|
278
|
+
"mn",
|
|
279
|
+
// Mongolian
|
|
280
|
+
"my",
|
|
281
|
+
// Myanmar (Burmese)
|
|
282
|
+
"ne",
|
|
283
|
+
// Nepali
|
|
284
|
+
"no",
|
|
285
|
+
// Norwegian
|
|
286
|
+
"or",
|
|
287
|
+
// Odia
|
|
288
|
+
"om",
|
|
289
|
+
// Oromo
|
|
290
|
+
"ps",
|
|
291
|
+
// Pashto
|
|
292
|
+
"fa",
|
|
293
|
+
// Persian
|
|
294
|
+
"pl",
|
|
295
|
+
// Polish
|
|
296
|
+
"pt",
|
|
297
|
+
// Portuguese
|
|
298
|
+
"pt_br",
|
|
299
|
+
// Portuguese (Brazil)
|
|
300
|
+
"pa",
|
|
301
|
+
// Punjabi
|
|
302
|
+
"qu",
|
|
303
|
+
// Quechua
|
|
304
|
+
"ro",
|
|
305
|
+
// Romanian
|
|
141
306
|
"ru",
|
|
142
307
|
// Russian
|
|
143
|
-
"
|
|
144
|
-
//
|
|
145
|
-
"
|
|
146
|
-
//
|
|
308
|
+
"sm",
|
|
309
|
+
// Samoan
|
|
310
|
+
"sa",
|
|
311
|
+
// Sanskrit
|
|
312
|
+
"gd",
|
|
313
|
+
// Scottish Gaelic
|
|
314
|
+
"sr",
|
|
315
|
+
// Serbian
|
|
316
|
+
"st",
|
|
317
|
+
// Sesotho
|
|
318
|
+
"sn",
|
|
319
|
+
// Shona
|
|
320
|
+
"sd",
|
|
321
|
+
// Sindhi
|
|
322
|
+
"si",
|
|
323
|
+
// Sinhala
|
|
324
|
+
"sk",
|
|
325
|
+
// Slovak
|
|
326
|
+
"sl",
|
|
327
|
+
// Slovenian
|
|
328
|
+
"so",
|
|
329
|
+
// Somali
|
|
330
|
+
"es",
|
|
331
|
+
// Spanish
|
|
332
|
+
"su",
|
|
333
|
+
// Sundanese
|
|
334
|
+
"sw",
|
|
335
|
+
// Swahili
|
|
336
|
+
"sv",
|
|
337
|
+
// Swedish
|
|
338
|
+
"tg",
|
|
339
|
+
// Tajik
|
|
340
|
+
"ta",
|
|
341
|
+
// Tamil
|
|
342
|
+
"tt",
|
|
343
|
+
// Tatar
|
|
344
|
+
"te",
|
|
345
|
+
// Telugu
|
|
346
|
+
"th",
|
|
347
|
+
// Thai
|
|
348
|
+
"ti",
|
|
349
|
+
// Tigrinya
|
|
350
|
+
"ts",
|
|
351
|
+
// Tsonga
|
|
147
352
|
"tr",
|
|
148
353
|
// Turkish
|
|
149
|
-
"
|
|
150
|
-
//
|
|
151
|
-
"
|
|
152
|
-
//
|
|
153
|
-
"
|
|
154
|
-
//
|
|
155
|
-
"
|
|
156
|
-
//
|
|
354
|
+
"tk",
|
|
355
|
+
// Turkmen
|
|
356
|
+
"ak",
|
|
357
|
+
// Twi
|
|
358
|
+
"uk",
|
|
359
|
+
// Ukrainian
|
|
360
|
+
"ur",
|
|
361
|
+
// Urdu
|
|
362
|
+
"ug",
|
|
363
|
+
// Uyghur
|
|
364
|
+
"uz",
|
|
365
|
+
// Uzbek
|
|
366
|
+
"vi",
|
|
367
|
+
// Vietnamese
|
|
368
|
+
"cy",
|
|
369
|
+
// Welsh
|
|
370
|
+
"xh",
|
|
371
|
+
// Xhosa
|
|
372
|
+
"yi",
|
|
373
|
+
// Yiddish
|
|
374
|
+
"yo",
|
|
375
|
+
// Yoruba
|
|
376
|
+
"zu"
|
|
377
|
+
// Zulu
|
|
157
378
|
];
|
|
158
379
|
}
|
|
159
380
|
});
|
|
@@ -255,7 +476,8 @@ function initTranslations(projectRoot, config = {}) {
|
|
|
255
476
|
ERROR: "Error",
|
|
256
477
|
SUCCESS: "Success"
|
|
257
478
|
};
|
|
258
|
-
fs2.writeFileSync(commonPath, JSON.stringify(sampleTranslations, null, 2)
|
|
479
|
+
fs2.writeFileSync(commonPath, `${JSON.stringify(sampleTranslations, null, 2)}
|
|
480
|
+
`, "utf-8");
|
|
259
481
|
console.log(`Created sample file: ${commonPath}`);
|
|
260
482
|
}
|
|
261
483
|
for (const lang of languages) {
|
|
@@ -275,7 +497,8 @@ function initTranslations(projectRoot, config = {}) {
|
|
|
275
497
|
sourceLanguage,
|
|
276
498
|
typesOutputPath: finalConfig.typesOutputPath
|
|
277
499
|
};
|
|
278
|
-
fs2.writeFileSync(configPath, JSON.stringify(configContent, null, 2)
|
|
500
|
+
fs2.writeFileSync(configPath, `${JSON.stringify(configContent, null, 2)}
|
|
501
|
+
`, "utf-8");
|
|
279
502
|
console.log(`Created config file: ${configPath}`);
|
|
280
503
|
}
|
|
281
504
|
console.log("=====");
|
|
@@ -357,7 +580,10 @@ function generateTranslationTypes(projectRoot = process.cwd()) {
|
|
|
357
580
|
console.log(`Generated types with ${allKeys.length} keys and ${namespaces.length} namespaces`);
|
|
358
581
|
console.log(`Output: ${outputFilePath}`);
|
|
359
582
|
try {
|
|
360
|
-
execSync(`pnpm biome format --write ${outputFilePath}`, {
|
|
583
|
+
execSync(`pnpm biome format --write ${outputFilePath}`, {
|
|
584
|
+
stdio: "inherit",
|
|
585
|
+
cwd: projectRoot
|
|
586
|
+
});
|
|
361
587
|
} catch {
|
|
362
588
|
console.warn("Failed to format with Biome, continuing without formatting...");
|
|
363
589
|
}
|
|
@@ -384,10 +610,10 @@ var init_generate_types = __esm({
|
|
|
384
610
|
// src/cli/translations.ts
|
|
385
611
|
init_esm_shims();
|
|
386
612
|
import "dotenv/config";
|
|
387
|
-
import { confirm as confirm2, input as input2, select } from "@inquirer/prompts";
|
|
388
613
|
import * as fs5 from "fs";
|
|
389
614
|
import * as path10 from "path";
|
|
390
615
|
import { parseArgs } from "util";
|
|
616
|
+
import { confirm as confirm2, input as input2, select } from "@inquirer/prompts";
|
|
391
617
|
|
|
392
618
|
// src/translations/cli/add-key.ts
|
|
393
619
|
init_esm_shims();
|
|
@@ -395,10 +621,10 @@ import * as path4 from "path";
|
|
|
395
621
|
|
|
396
622
|
// src/translations/utils/translator.ts
|
|
397
623
|
init_esm_shims();
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
624
|
+
|
|
625
|
+
// src/translations/utils/google-translate-provider.ts
|
|
626
|
+
init_esm_shims();
|
|
627
|
+
function preserveVariables(text) {
|
|
402
628
|
const variableMap = /* @__PURE__ */ new Map();
|
|
403
629
|
let placeholderIndex = 0;
|
|
404
630
|
const textWithPlaceholders = text.replace(/\{\{([^}]+)\}\}/g, (match) => {
|
|
@@ -407,29 +633,81 @@ async function translateText(text, targetLang, sourceLang = "en", apiKey) {
|
|
|
407
633
|
placeholderIndex++;
|
|
408
634
|
return placeholder;
|
|
409
635
|
});
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
"Content-Type": "application/json"
|
|
415
|
-
},
|
|
416
|
-
body: JSON.stringify({
|
|
417
|
-
q: textWithPlaceholders,
|
|
418
|
-
source: sourceLang,
|
|
419
|
-
target: targetLang.split("_")[0],
|
|
420
|
-
// Convert 'pt_BR' to 'pt'
|
|
421
|
-
format: "text"
|
|
422
|
-
})
|
|
423
|
-
});
|
|
424
|
-
const data = await response.json();
|
|
425
|
-
if (data.error) {
|
|
426
|
-
throw new Error(`Google Translate API error: ${data.error.message}`);
|
|
427
|
-
}
|
|
428
|
-
let translatedText = data.data.translations[0].translatedText;
|
|
636
|
+
return { textWithPlaceholders, variableMap };
|
|
637
|
+
}
|
|
638
|
+
function restoreVariables(text, variableMap) {
|
|
639
|
+
let result = text;
|
|
429
640
|
for (const [placeholder, original] of variableMap) {
|
|
430
|
-
|
|
641
|
+
result = result.replace(new RegExp(placeholder, "g"), original);
|
|
642
|
+
}
|
|
643
|
+
return result;
|
|
644
|
+
}
|
|
645
|
+
var GoogleTranslateProvider = class {
|
|
646
|
+
async translate(options) {
|
|
647
|
+
const { text, sourceLang, targetLang, apiKey } = options;
|
|
648
|
+
if (!apiKey) {
|
|
649
|
+
throw new Error(
|
|
650
|
+
"Google Translate API key is required. Set GOOGLE_TRANSLATE_API_KEY environment variable or provide apiKey in options."
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
const { textWithPlaceholders, variableMap } = preserveVariables(text);
|
|
654
|
+
const url = `https://translation.googleapis.com/language/translate/v2?key=${apiKey}`;
|
|
655
|
+
const response = await fetch(url, {
|
|
656
|
+
method: "POST",
|
|
657
|
+
headers: {
|
|
658
|
+
"Content-Type": "application/json"
|
|
659
|
+
},
|
|
660
|
+
body: JSON.stringify({
|
|
661
|
+
q: textWithPlaceholders,
|
|
662
|
+
source: sourceLang,
|
|
663
|
+
target: targetLang.split("_")[0],
|
|
664
|
+
// Convert 'pt_BR' to 'pt'
|
|
665
|
+
format: "text"
|
|
666
|
+
})
|
|
667
|
+
});
|
|
668
|
+
const data = await response.json();
|
|
669
|
+
if (data.error) {
|
|
670
|
+
throw new Error(`Google Translate API error: ${data.error.message}`);
|
|
671
|
+
}
|
|
672
|
+
const translatedText = data.data.translations[0].translatedText;
|
|
673
|
+
return restoreVariables(translatedText, variableMap);
|
|
674
|
+
}
|
|
675
|
+
async translateBatch(texts, sourceLang, targetLang, apiKey, delayMs = 100) {
|
|
676
|
+
const results = [];
|
|
677
|
+
for (const text of texts) {
|
|
678
|
+
const translated = await this.translate({
|
|
679
|
+
text,
|
|
680
|
+
sourceLang,
|
|
681
|
+
targetLang,
|
|
682
|
+
apiKey
|
|
683
|
+
});
|
|
684
|
+
results.push(translated);
|
|
685
|
+
if (delayMs > 0) {
|
|
686
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return results;
|
|
431
690
|
}
|
|
432
|
-
|
|
691
|
+
async validateConfig() {
|
|
692
|
+
const apiKey = process.env.GOOGLE_TRANSLATE_API_KEY;
|
|
693
|
+
return !!apiKey;
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
// src/translations/utils/translator.ts
|
|
698
|
+
var defaultProvider = new GoogleTranslateProvider();
|
|
699
|
+
var customProvider = null;
|
|
700
|
+
function getTranslationProvider() {
|
|
701
|
+
return customProvider || defaultProvider;
|
|
702
|
+
}
|
|
703
|
+
async function translateText(text, targetLang, sourceLang = "en", apiKey) {
|
|
704
|
+
const provider = getTranslationProvider();
|
|
705
|
+
return provider.translate({
|
|
706
|
+
text,
|
|
707
|
+
sourceLang,
|
|
708
|
+
targetLang,
|
|
709
|
+
apiKey
|
|
710
|
+
});
|
|
433
711
|
}
|
|
434
712
|
|
|
435
713
|
// src/translations/cli/add-key.ts
|