@adminforth/i18n 1.0.13 → 1.0.16-next.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/Changelog.md +5 -0
- package/dist/index.js +18 -8
- package/index.ts +20 -9
- package/package.json +3 -1
package/Changelog.md
CHANGED
|
@@ -6,7 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
## [1.0.14]
|
|
9
10
|
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Add `ignoreInitial` for watch to prevent initial messages loading
|
|
14
|
+
- Add locking mechanism to prevent initial messages loading call in parallel (just in case)
|
|
10
15
|
|
|
11
16
|
## [1.0.13]
|
|
12
17
|
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,8 @@ 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
|
+
import { AsyncQueue } from '@sapphire/async-queue';
|
|
16
|
+
const processFrontendMessagesQueue = new AsyncQueue();
|
|
15
17
|
const SLAVIC_PLURAL_EXAMPLES = {
|
|
16
18
|
uk: 'яблук | Яблуко | Яблука | Яблук', // zero | singular | 2-4 | 5+
|
|
17
19
|
bg: 'ябълки | ябълка | ябълки | ябълки', // zero | singular | 2-4 | 5+
|
|
@@ -275,19 +277,23 @@ export default class I18N extends AdminForthPlugin {
|
|
|
275
277
|
confirm: 'Are you sure you want to translate selected items?',
|
|
276
278
|
state: 'selected',
|
|
277
279
|
action: (_j) => __awaiter(this, [_j], void 0, function* ({ selectedIds, tr }) {
|
|
280
|
+
let translatedCount = 0;
|
|
278
281
|
try {
|
|
279
|
-
yield this.bulkTranslate({ selectedIds });
|
|
282
|
+
translatedCount = yield this.bulkTranslate({ selectedIds });
|
|
280
283
|
}
|
|
281
284
|
catch (e) {
|
|
282
285
|
if (e instanceof AiTranslateError) {
|
|
286
|
+
process.env.HEAVY_DEBUG && console.error('🪲⛔ bulkTranslate error', e);
|
|
283
287
|
return { ok: false, error: e.message };
|
|
284
288
|
}
|
|
285
289
|
}
|
|
286
|
-
console.log('🪲bulkTranslate done', selectedIds);
|
|
290
|
+
process.env.HEAVY_DEBUG && console.log('🪲bulkTranslate done', selectedIds);
|
|
287
291
|
this.updateUntranslatedMenuBadge();
|
|
288
292
|
return {
|
|
289
293
|
ok: true, error: undefined,
|
|
290
|
-
successMessage: yield tr(`Translated {count} items`, 'backend', {
|
|
294
|
+
successMessage: yield tr(`Translated {count} items`, 'backend', {
|
|
295
|
+
count: translatedCount,
|
|
296
|
+
}),
|
|
291
297
|
};
|
|
292
298
|
})
|
|
293
299
|
});
|
|
@@ -349,7 +355,7 @@ export default class I18N extends AdminForthPlugin {
|
|
|
349
355
|
let totalTranslated = 0;
|
|
350
356
|
for (let i = 0; i < strings.length; i += maxKeysInOneReq) {
|
|
351
357
|
const slicedStrings = strings.slice(i, i + maxKeysInOneReq);
|
|
352
|
-
console.log('🪲🔪slicedStrings ', slicedStrings);
|
|
358
|
+
process.env.HEAVY_DEBUG && console.log('🪲🔪slicedStrings len', slicedStrings.length);
|
|
353
359
|
totalTranslated += yield translateToLang(langIsoCode, slicedStrings, plurals);
|
|
354
360
|
}
|
|
355
361
|
return totalTranslated;
|
|
@@ -368,10 +374,10 @@ ${JSON.stringify(strings.reduce((acc, s) => {
|
|
|
368
374
|
}, {}), null, 2)}
|
|
369
375
|
\`\`\`
|
|
370
376
|
`;
|
|
371
|
-
process.env.HEAVY_DEBUG && console.log('llm prompt', prompt);
|
|
377
|
+
process.env.HEAVY_DEBUG && console.log('🧠 llm prompt', prompt);
|
|
372
378
|
// call OpenAI
|
|
373
379
|
const resp = yield this.options.completeAdapter.complete(prompt, [], 300);
|
|
374
|
-
process.env.HEAVY_DEBUG && console.log('llm resp', resp);
|
|
380
|
+
process.env.HEAVY_DEBUG && console.log('🧠 llm resp', resp);
|
|
375
381
|
if (resp.error) {
|
|
376
382
|
throw new AiTranslateError(resp.error);
|
|
377
383
|
}
|
|
@@ -386,7 +392,7 @@ ${JSON.stringify(strings.reduce((acc, s) => {
|
|
|
386
392
|
}
|
|
387
393
|
catch (e) {
|
|
388
394
|
console.error('error in parsing OpenAI', resp);
|
|
389
|
-
|
|
395
|
+
throw new AiTranslateError('Error in parsing OpenAI response');
|
|
390
396
|
}
|
|
391
397
|
res = JSON.parse(res);
|
|
392
398
|
for (const [enStr, translatedStr] of Object.entries(res)) {
|
|
@@ -433,6 +439,7 @@ ${JSON.stringify(strings.reduce((acc, s) => {
|
|
|
433
439
|
}
|
|
434
440
|
processExtractedMessages(adminforth, filePath) {
|
|
435
441
|
return __awaiter(this, void 0, void 0, function* () {
|
|
442
|
+
yield processFrontendMessagesQueue.wait();
|
|
436
443
|
// messages file is in i18n-messages.json
|
|
437
444
|
let messages;
|
|
438
445
|
try {
|
|
@@ -482,7 +489,10 @@ ${JSON.stringify(strings.reduce((acc, s) => {
|
|
|
482
489
|
this.processExtractedMessages(adminforth, messagesFile);
|
|
483
490
|
// we use watcher because file can't be yet created when we start - bundleNow can be done in build time or can be done now
|
|
484
491
|
// that is why we make attempt to process it now and then watch for changes
|
|
485
|
-
const w = chokidar.watch(messagesFile, {
|
|
492
|
+
const w = chokidar.watch(messagesFile, {
|
|
493
|
+
persistent: true,
|
|
494
|
+
ignoreInitial: true, // don't trigger 'add' event for existing file on start
|
|
495
|
+
});
|
|
486
496
|
w.on('change', () => {
|
|
487
497
|
process.env.HEAVY_DEBUG && console.log('🪲🔔messagesFile change', messagesFile);
|
|
488
498
|
this.processExtractedMessages(adminforth, messagesFile);
|
package/index.ts
CHANGED
|
@@ -5,6 +5,9 @@ import iso6391, { LanguageCode } from 'iso-639-1';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
7
|
import chokidar from 'chokidar';
|
|
8
|
+
import { AsyncQueue } from '@sapphire/async-queue';
|
|
9
|
+
|
|
10
|
+
const processFrontendMessagesQueue = new AsyncQueue();
|
|
8
11
|
|
|
9
12
|
const SLAVIC_PLURAL_EXAMPLES = {
|
|
10
13
|
uk: 'яблук | Яблуко | Яблука | Яблук', // zero | singular | 2-4 | 5+
|
|
@@ -315,18 +318,22 @@ export default class I18N extends AdminForthPlugin {
|
|
|
315
318
|
confirm: 'Are you sure you want to translate selected items?',
|
|
316
319
|
state: 'selected',
|
|
317
320
|
action: async ({ selectedIds, tr }) => {
|
|
321
|
+
let translatedCount = 0;
|
|
318
322
|
try {
|
|
319
|
-
await this.bulkTranslate({ selectedIds });
|
|
323
|
+
translatedCount = await this.bulkTranslate({ selectedIds });
|
|
320
324
|
} catch (e) {
|
|
321
325
|
if (e instanceof AiTranslateError) {
|
|
326
|
+
process.env.HEAVY_DEBUG && console.error('🪲⛔ bulkTranslate error', e);
|
|
322
327
|
return { ok: false, error: e.message };
|
|
323
328
|
}
|
|
324
329
|
}
|
|
325
|
-
console.log('🪲bulkTranslate done', selectedIds);
|
|
330
|
+
process.env.HEAVY_DEBUG && console.log('🪲bulkTranslate done', selectedIds);
|
|
326
331
|
this.updateUntranslatedMenuBadge();
|
|
327
332
|
return {
|
|
328
333
|
ok: true, error: undefined,
|
|
329
|
-
successMessage: await tr(`Translated {count} items`, 'backend', {
|
|
334
|
+
successMessage: await tr(`Translated {count} items`, 'backend', {
|
|
335
|
+
count: translatedCount,
|
|
336
|
+
}),
|
|
330
337
|
};
|
|
331
338
|
}
|
|
332
339
|
}
|
|
@@ -408,7 +415,7 @@ export default class I18N extends AdminForthPlugin {
|
|
|
408
415
|
let totalTranslated = 0;
|
|
409
416
|
for (let i = 0; i < strings.length; i += maxKeysInOneReq) {
|
|
410
417
|
const slicedStrings = strings.slice(i, i + maxKeysInOneReq);
|
|
411
|
-
console.log('🪲🔪slicedStrings ', slicedStrings);
|
|
418
|
+
process.env.HEAVY_DEBUG && console.log('🪲🔪slicedStrings len', slicedStrings.length);
|
|
412
419
|
totalTranslated += await translateToLang(langIsoCode, slicedStrings, plurals);
|
|
413
420
|
}
|
|
414
421
|
return totalTranslated;
|
|
@@ -432,7 +439,7 @@ ${
|
|
|
432
439
|
\`\`\`
|
|
433
440
|
`;
|
|
434
441
|
|
|
435
|
-
process.env.HEAVY_DEBUG && console.log('llm prompt', prompt);
|
|
442
|
+
process.env.HEAVY_DEBUG && console.log('🧠 llm prompt', prompt);
|
|
436
443
|
|
|
437
444
|
// call OpenAI
|
|
438
445
|
const resp = await this.options.completeAdapter.complete(
|
|
@@ -441,7 +448,7 @@ ${
|
|
|
441
448
|
300,
|
|
442
449
|
);
|
|
443
450
|
|
|
444
|
-
process.env.HEAVY_DEBUG && console.log('llm resp', resp);
|
|
451
|
+
process.env.HEAVY_DEBUG && console.log('🧠 llm resp', resp);
|
|
445
452
|
|
|
446
453
|
if (resp.error) {
|
|
447
454
|
throw new AiTranslateError(resp.error);
|
|
@@ -457,7 +464,7 @@ ${
|
|
|
457
464
|
res = resp.content.split("```json")[1].split("```")[0];
|
|
458
465
|
} catch (e) {
|
|
459
466
|
console.error('error in parsing OpenAI', resp);
|
|
460
|
-
|
|
467
|
+
throw new AiTranslateError('Error in parsing OpenAI response');
|
|
461
468
|
}
|
|
462
469
|
res = JSON.parse(res);
|
|
463
470
|
|
|
@@ -524,6 +531,7 @@ ${
|
|
|
524
531
|
}
|
|
525
532
|
|
|
526
533
|
async processExtractedMessages(adminforth: IAdminForth, filePath: string) {
|
|
534
|
+
await processFrontendMessagesQueue.wait();
|
|
527
535
|
// messages file is in i18n-messages.json
|
|
528
536
|
let messages;
|
|
529
537
|
try {
|
|
@@ -535,7 +543,7 @@ ${
|
|
|
535
543
|
return;
|
|
536
544
|
}
|
|
537
545
|
// loop over missingKeys[i].path and add them to database if not exists
|
|
538
|
-
|
|
546
|
+
|
|
539
547
|
const missingKeysDeduplicated = messages.missingKeys.reduce((acc: any[], missingKey: any) => {
|
|
540
548
|
if (!acc.find((a) => a.path === missingKey.path)) {
|
|
541
549
|
acc.push(missingKey);
|
|
@@ -579,7 +587,10 @@ ${
|
|
|
579
587
|
this.processExtractedMessages(adminforth, messagesFile);
|
|
580
588
|
// we use watcher because file can't be yet created when we start - bundleNow can be done in build time or can be done now
|
|
581
589
|
// that is why we make attempt to process it now and then watch for changes
|
|
582
|
-
const w = chokidar.watch(messagesFile, {
|
|
590
|
+
const w = chokidar.watch(messagesFile, {
|
|
591
|
+
persistent: true,
|
|
592
|
+
ignoreInitial: true, // don't trigger 'add' event for existing file on start
|
|
593
|
+
});
|
|
583
594
|
w.on('change', () => {
|
|
584
595
|
process.env.HEAVY_DEBUG && console.log('🪲🔔messagesFile change', messagesFile);
|
|
585
596
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adminforth/i18n",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16-next.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc && rsync -av --exclude 'node_modules' custom dist/ && npm version patch",
|
|
9
9
|
"rollout": "npm run build && npm publish --access public",
|
|
10
|
+
"rollout-next": "npm run build && npm version prerelease --preid=next && npm publish --tag next",
|
|
10
11
|
"prepare": "npm link adminforth"
|
|
11
12
|
},
|
|
12
13
|
"keywords": [],
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
"description": "",
|
|
16
17
|
"dependencies": {
|
|
17
18
|
"@aws-sdk/client-ses": "^3.654.0",
|
|
19
|
+
"@sapphire/async-queue": "^1.5.5",
|
|
18
20
|
"chokidar": "^4.0.1",
|
|
19
21
|
"iso-639-1": "^3.1.3"
|
|
20
22
|
},
|