@adminforth/i18n 1.0.8 → 1.0.10
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/Changelog.md +13 -0
- package/dist/index.js +37 -8
- package/index.ts +53 -12
- package/package.json +1 -1
package/Changelog.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [v1.0.10]
|
|
9
|
+
|
|
10
|
+
## Fixed
|
|
11
|
+
|
|
12
|
+
- fix automatic translations for duplicate strings
|
|
13
|
+
- improve slavik pluralization generations by splitting the requests
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,19 @@ import iso6391 from 'iso-639-1';
|
|
|
12
12
|
import path from 'path';
|
|
13
13
|
import fs from 'fs-extra';
|
|
14
14
|
import chokidar from 'chokidar';
|
|
15
|
+
const SLAVIC_PLURAL_EXAMPLES = {
|
|
16
|
+
uk: 'яблук | Яблуко | Яблука | Яблук', // zero | singular | 2-4 | 5+
|
|
17
|
+
bg: 'ябълки | ябълка | ябълки | ябълки', // zero | singular | 2-4 | 5+
|
|
18
|
+
cs: 'jablek | jablko | jablka | jablek', // zero | singular | 2-4 | 5+
|
|
19
|
+
hr: 'jabuka | jabuka | jabuke | jabuka', // zero | singular | 2-4 | 5+
|
|
20
|
+
mk: 'јаболка | јаболко | јаболка | јаболка', // zero | singular | 2-4 | 5+
|
|
21
|
+
pl: 'jabłek | jabłko | jabłka | jabłek', // zero | singular | 2-4 | 5+
|
|
22
|
+
sk: 'jabĺk | jablko | jablká | jabĺk', // zero | singular | 2-4 | 5+
|
|
23
|
+
sl: 'jabolk | jabolko | jabolka | jabolk', // zero | singular | 2-4 | 5+
|
|
24
|
+
sr: 'јабука | јабука | јабуке | јабука', // zero | singular | 2-4 | 5+
|
|
25
|
+
be: 'яблыкаў | яблык | яблыкі | яблыкаў', // zero | singular | 2-4 | 5+
|
|
26
|
+
ru: 'яблок | яблоко | яблока | яблок', // zero | singular | 2-4 | 5+
|
|
27
|
+
};
|
|
15
28
|
class CachingAdapterMemory {
|
|
16
29
|
constructor() {
|
|
17
30
|
this.cache = {};
|
|
@@ -295,6 +308,7 @@ export default class I18N extends AdminForthPlugin {
|
|
|
295
308
|
});
|
|
296
309
|
});
|
|
297
310
|
}
|
|
311
|
+
// returns translated count
|
|
298
312
|
bulkTranslate(_a) {
|
|
299
313
|
return __awaiter(this, arguments, void 0, function* ({ selectedIds }) {
|
|
300
314
|
const needToTranslateByLang = {};
|
|
@@ -318,17 +332,24 @@ export default class I18N extends AdminForthPlugin {
|
|
|
318
332
|
}
|
|
319
333
|
const maxKeysInOneReq = 10;
|
|
320
334
|
const updateStrings = {};
|
|
321
|
-
const translateToLang = (
|
|
335
|
+
const translateToLang = (langIsoCode_1, strings_1, ...args_1) => __awaiter(this, [langIsoCode_1, strings_1, ...args_1], void 0, function* (langIsoCode, strings, plurals = false) {
|
|
336
|
+
if (strings.length === 0) {
|
|
337
|
+
return 0;
|
|
338
|
+
}
|
|
322
339
|
if (strings.length > maxKeysInOneReq) {
|
|
340
|
+
let totalTranslated = 0;
|
|
323
341
|
for (let i = 0; i < strings.length; i += maxKeysInOneReq) {
|
|
324
342
|
const slicedStrings = strings.slice(i, i + maxKeysInOneReq);
|
|
325
|
-
|
|
343
|
+
console.log('🪲🔪slicedStrings ', slicedStrings);
|
|
344
|
+
totalTranslated += yield translateToLang(langIsoCode, slicedStrings, plurals);
|
|
326
345
|
}
|
|
327
|
-
return;
|
|
346
|
+
return totalTranslated;
|
|
328
347
|
}
|
|
329
348
|
const lang = langIsoCode;
|
|
349
|
+
const requestSlavicPlurals = Object.keys(SLAVIC_PLURAL_EXAMPLES).includes(lang) && plurals;
|
|
330
350
|
const prompt = `
|
|
331
351
|
I need to translate strings in JSON to ${lang} language from English for my web app.
|
|
352
|
+
${requestSlavicPlurals ? `You should provide 4 translations (in format zero | singular | 2-4 | 5+) e.g. ${SLAVIC_PLURAL_EXAMPLES[lang]}` : ''}
|
|
332
353
|
Keep keys, as is, write translation into values! Here are the strings:
|
|
333
354
|
|
|
334
355
|
\`\`\`json
|
|
@@ -363,22 +384,29 @@ ${JSON.stringify(strings.reduce((acc, s) => {
|
|
|
363
384
|
const translationsTargeted = translations.filter(t => t[this.enFieldName] === enStr);
|
|
364
385
|
// might be several with same en_string
|
|
365
386
|
for (const translation of translationsTargeted) {
|
|
366
|
-
translation[this.trFieldNames[lang]] = translatedStr;
|
|
387
|
+
//translation[this.trFieldNames[lang]] = translatedStr;
|
|
367
388
|
// process.env.HEAVY_DEBUG && console.log(`🪲translated to ${lang} ${translation.en_string}, ${translatedStr}`)
|
|
368
|
-
if (!updateStrings[
|
|
369
|
-
updateStrings[
|
|
389
|
+
if (!updateStrings[translation[this.primaryKeyFieldName]]) {
|
|
390
|
+
updateStrings[translation[this.primaryKeyFieldName]] = {
|
|
370
391
|
updates: {},
|
|
392
|
+
translatedStr,
|
|
371
393
|
category: translation[this.options.categoryFieldName],
|
|
372
394
|
strId: translation[this.primaryKeyFieldName],
|
|
373
395
|
};
|
|
374
396
|
}
|
|
375
|
-
updateStrings[
|
|
397
|
+
updateStrings[translation[this.primaryKeyFieldName]].updates[this.trFieldNames[lang]] = translatedStr;
|
|
376
398
|
}
|
|
377
399
|
}
|
|
400
|
+
return res.length;
|
|
378
401
|
});
|
|
379
402
|
const langsInvolved = new Set(Object.keys(needToTranslateByLang));
|
|
403
|
+
let totalTranslated = 0;
|
|
380
404
|
yield Promise.all(Object.entries(needToTranslateByLang).map((_b) => __awaiter(this, [_b], void 0, function* ([lang, strings]) {
|
|
381
|
-
|
|
405
|
+
// first translate without plurals
|
|
406
|
+
const stringsWithoutPlurals = strings.filter(s => !s.en_string.includes('|'));
|
|
407
|
+
totalTranslated += yield translateToLang(lang, stringsWithoutPlurals, false);
|
|
408
|
+
const stringsWithPlurals = strings.filter(s => s.en_string.includes('|'));
|
|
409
|
+
totalTranslated += yield translateToLang(lang, stringsWithPlurals, true);
|
|
382
410
|
})));
|
|
383
411
|
yield Promise.all(Object.entries(updateStrings).map((_c) => __awaiter(this, [_c], void 0, function* ([_, { updates, strId }]) {
|
|
384
412
|
// because this will translate all languages, we can set completedLangs to all languages
|
|
@@ -391,6 +419,7 @@ ${JSON.stringify(strings.reduce((acc, s) => {
|
|
|
391
419
|
this.cache.clear(`${this.resourceConfig.resourceId}:${category}:${lang}:${enStr}`);
|
|
392
420
|
}
|
|
393
421
|
}
|
|
422
|
+
return totalTranslated;
|
|
394
423
|
});
|
|
395
424
|
}
|
|
396
425
|
processExtractedMessages(adminforth, filePath) {
|
package/index.ts
CHANGED
|
@@ -6,6 +6,20 @@ import path from 'path';
|
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
7
|
import chokidar from 'chokidar';
|
|
8
8
|
|
|
9
|
+
const SLAVIC_PLURAL_EXAMPLES = {
|
|
10
|
+
uk: 'яблук | Яблуко | Яблука | Яблук', // zero | singular | 2-4 | 5+
|
|
11
|
+
bg: 'ябълки | ябълка | ябълки | ябълки', // zero | singular | 2-4 | 5+
|
|
12
|
+
cs: 'jablek | jablko | jablka | jablek', // zero | singular | 2-4 | 5+
|
|
13
|
+
hr: 'jabuka | jabuka | jabuke | jabuka', // zero | singular | 2-4 | 5+
|
|
14
|
+
mk: 'јаболка | јаболко | јаболка | јаболка', // zero | singular | 2-4 | 5+
|
|
15
|
+
pl: 'jabłek | jabłko | jabłka | jabłek', // zero | singular | 2-4 | 5+
|
|
16
|
+
sk: 'jabĺk | jablko | jablká | jabĺk', // zero | singular | 2-4 | 5+
|
|
17
|
+
sl: 'jabolk | jabolko | jabolka | jabolk', // zero | singular | 2-4 | 5+
|
|
18
|
+
sr: 'јабука | јабука | јабуке | јабука', // zero | singular | 2-4 | 5+
|
|
19
|
+
be: 'яблыкаў | яблык | яблыкі | яблыкаў', // zero | singular | 2-4 | 5+
|
|
20
|
+
ru: 'яблок | яблоко | яблока | яблок', // zero | singular | 2-4 | 5+
|
|
21
|
+
};
|
|
22
|
+
|
|
9
23
|
interface ICachingAdapter {
|
|
10
24
|
get(key: string): Promise<any>;
|
|
11
25
|
set(key: string, value: any): Promise<void>;
|
|
@@ -333,7 +347,8 @@ export default class I18N extends AdminForthPlugin {
|
|
|
333
347
|
});
|
|
334
348
|
}
|
|
335
349
|
|
|
336
|
-
|
|
350
|
+
// returns translated count
|
|
351
|
+
async bulkTranslate({ selectedIds }: { selectedIds: string[] }): Promise<number> {
|
|
337
352
|
|
|
338
353
|
const needToTranslateByLang : Partial<
|
|
339
354
|
Record<
|
|
@@ -368,22 +383,33 @@ export default class I18N extends AdminForthPlugin {
|
|
|
368
383
|
const maxKeysInOneReq = 10;
|
|
369
384
|
|
|
370
385
|
const updateStrings: Record<string, {
|
|
371
|
-
updates: any,
|
|
386
|
+
updates: any,
|
|
387
|
+
category: string,
|
|
388
|
+
strId: string,
|
|
389
|
+
translatedStr: string
|
|
372
390
|
}> = {};
|
|
373
391
|
|
|
374
|
-
const translateToLang = async (langIsoCode: LanguageCode, strings: { en_string: string, category: string }[]) => {
|
|
375
|
-
|
|
392
|
+
const translateToLang = async (langIsoCode: LanguageCode, strings: { en_string: string, category: string }[], plurals=false): Promise<number> => {
|
|
393
|
+
if (strings.length === 0) {
|
|
394
|
+
return 0;
|
|
395
|
+
}
|
|
376
396
|
|
|
377
397
|
if (strings.length > maxKeysInOneReq) {
|
|
398
|
+
let totalTranslated = 0;
|
|
378
399
|
for (let i = 0; i < strings.length; i += maxKeysInOneReq) {
|
|
379
400
|
const slicedStrings = strings.slice(i, i + maxKeysInOneReq);
|
|
380
|
-
|
|
401
|
+
console.log('🪲🔪slicedStrings ', slicedStrings);
|
|
402
|
+
totalTranslated += await translateToLang(langIsoCode, slicedStrings, plurals);
|
|
381
403
|
}
|
|
382
|
-
return;
|
|
404
|
+
return totalTranslated;
|
|
383
405
|
}
|
|
384
406
|
const lang = langIsoCode;
|
|
407
|
+
|
|
408
|
+
const requestSlavicPlurals = Object.keys(SLAVIC_PLURAL_EXAMPLES).includes(lang) && plurals;
|
|
409
|
+
|
|
385
410
|
const prompt = `
|
|
386
411
|
I need to translate strings in JSON to ${lang} language from English for my web app.
|
|
412
|
+
${requestSlavicPlurals ? `You should provide 4 translations (in format zero | singular | 2-4 | 5+) e.g. ${SLAVIC_PLURAL_EXAMPLES[lang]}` : ''}
|
|
387
413
|
Keep keys, as is, write translation into values! Here are the strings:
|
|
388
414
|
|
|
389
415
|
\`\`\`json
|
|
@@ -424,29 +450,42 @@ ${
|
|
|
424
450
|
return;
|
|
425
451
|
}
|
|
426
452
|
res = JSON.parse(res);
|
|
427
|
-
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
for (const [enStr, translatedStr] of Object.entries(res) as [string, string][]) {
|
|
428
456
|
const translationsTargeted = translations.filter(t => t[this.enFieldName] === enStr);
|
|
429
457
|
// might be several with same en_string
|
|
430
458
|
for (const translation of translationsTargeted) {
|
|
431
|
-
translation[this.trFieldNames[lang]] = translatedStr;
|
|
459
|
+
//translation[this.trFieldNames[lang]] = translatedStr;
|
|
432
460
|
// process.env.HEAVY_DEBUG && console.log(`🪲translated to ${lang} ${translation.en_string}, ${translatedStr}`)
|
|
433
|
-
if (!updateStrings[
|
|
434
|
-
|
|
461
|
+
if (!updateStrings[translation[this.primaryKeyFieldName]]) {
|
|
462
|
+
|
|
463
|
+
updateStrings[translation[this.primaryKeyFieldName]] = {
|
|
435
464
|
updates: {},
|
|
465
|
+
translatedStr,
|
|
436
466
|
category: translation[this.options.categoryFieldName],
|
|
437
467
|
strId: translation[this.primaryKeyFieldName],
|
|
438
468
|
};
|
|
439
469
|
}
|
|
440
|
-
updateStrings[
|
|
470
|
+
updateStrings[
|
|
471
|
+
translation[this.primaryKeyFieldName]
|
|
472
|
+
].updates[this.trFieldNames[lang]] = translatedStr;
|
|
441
473
|
}
|
|
442
474
|
}
|
|
443
475
|
|
|
476
|
+
return res.length;
|
|
444
477
|
}
|
|
445
478
|
|
|
446
479
|
const langsInvolved = new Set(Object.keys(needToTranslateByLang));
|
|
447
480
|
|
|
481
|
+
let totalTranslated = 0;
|
|
448
482
|
await Promise.all(Object.entries(needToTranslateByLang).map(async ([lang, strings]: [LanguageCode, { en_string: string, category: string }[]]) => {
|
|
449
|
-
|
|
483
|
+
// first translate without plurals
|
|
484
|
+
const stringsWithoutPlurals = strings.filter(s => !s.en_string.includes('|'));
|
|
485
|
+
totalTranslated += await translateToLang(lang, stringsWithoutPlurals, false);
|
|
486
|
+
|
|
487
|
+
const stringsWithPlurals = strings.filter(s => s.en_string.includes('|'));
|
|
488
|
+
totalTranslated += await translateToLang(lang, stringsWithPlurals, true);
|
|
450
489
|
}));
|
|
451
490
|
|
|
452
491
|
await Promise.all(
|
|
@@ -470,6 +509,8 @@ ${
|
|
|
470
509
|
}
|
|
471
510
|
}
|
|
472
511
|
|
|
512
|
+
return totalTranslated;
|
|
513
|
+
|
|
473
514
|
}
|
|
474
515
|
|
|
475
516
|
async processExtractedMessages(adminforth: IAdminForth, filePath: string) {
|