transduck 0.2.1 → 0.2.2
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/dist/cli.js +82 -63
- package/dist/react/index.js +1 -0
- package/package.json +1 -1
- package/src/cli.ts +18 -0
- package/src/react/index.ts +2 -0
package/dist/cli.js
CHANGED
|
@@ -298,6 +298,7 @@ export async function runWarm(opts) {
|
|
|
298
298
|
export async function runScan(opts) {
|
|
299
299
|
const cfg = loadConfig(opts.configPath);
|
|
300
300
|
const scanDirs = opts.dirs.length > 0 ? opts.dirs : [process.cwd()];
|
|
301
|
+
console.log('Scanning...');
|
|
301
302
|
const entries = scanDirectory(scanDirs);
|
|
302
303
|
const regular = entries.filter(e => !e.plural);
|
|
303
304
|
const plurals = entries.filter(e => e.plural);
|
|
@@ -337,78 +338,96 @@ export async function runScan(opts) {
|
|
|
337
338
|
}
|
|
338
339
|
// Warm
|
|
339
340
|
if (opts.warm) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
});
|
|
341
|
+
if (entries.length === 0) {
|
|
342
|
+
lines.push('\nNothing to warm — no translatable strings found.');
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
const targetLangs = opts.langs && opts.langs.length > 0
|
|
346
|
+
? opts.langs.map(l => l.toUpperCase())
|
|
347
|
+
: cfg.targetLangs;
|
|
348
|
+
const store = new TranslationStore(cfg.storagePath);
|
|
349
|
+
await store.initialize();
|
|
350
|
+
const projectContextHash = hash(cfg.projectContext);
|
|
351
|
+
let translated = 0;
|
|
352
|
+
let skipped = 0;
|
|
353
|
+
let failed = 0;
|
|
354
|
+
const total = entries.length * targetLangs.length;
|
|
355
|
+
let done = 0;
|
|
356
|
+
for (const entry of entries) {
|
|
357
|
+
if (entry.plural) {
|
|
358
|
+
const sourceKey = entry.one + '\x00' + entry.other;
|
|
359
|
+
const stringContextHash = hash(entry.context ?? '');
|
|
360
|
+
const label = (entry.one ?? '').slice(0, 40);
|
|
361
|
+
for (const lang of targetLangs) {
|
|
362
|
+
done++;
|
|
363
|
+
const cachedForms = await store.lookupPlural({
|
|
364
|
+
sourceText: sourceKey, sourceLang: cfg.sourceLang, targetLang: lang,
|
|
365
|
+
projectContextHash, stringContextHash,
|
|
366
|
+
});
|
|
367
|
+
if (Object.keys(cachedForms).length > 0) {
|
|
368
|
+
skipped++;
|
|
369
|
+
console.log(` [${done}/${total}] ${lang} skipped (cached): ${label}`);
|
|
370
|
+
continue;
|
|
371
371
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
const cached = await store.lookup({
|
|
383
|
-
sourceText: entry.text, sourceLang: cfg.sourceLang, targetLang: lang,
|
|
384
|
-
projectContextHash, stringContextHash,
|
|
385
|
-
});
|
|
386
|
-
if (cached !== null) {
|
|
387
|
-
skipped++;
|
|
388
|
-
continue;
|
|
389
|
-
}
|
|
390
|
-
try {
|
|
391
|
-
const result = await backendTranslate(entry.text, cfg.sourceLang, lang, cfg.projectContext, entry.context ?? null, cfg);
|
|
392
|
-
if (validateTranslation(entry.text, result)) {
|
|
393
|
-
await store.insert({
|
|
394
|
-
sourceText: entry.text, sourceLang: cfg.sourceLang, targetLang: lang,
|
|
395
|
-
projectContextHash, stringContextHash,
|
|
396
|
-
translatedText: result, model: cfg.backendModel, status: 'translated',
|
|
397
|
-
});
|
|
372
|
+
try {
|
|
373
|
+
const forms = await backendTranslatePlural(entry.one, entry.other, cfg.sourceLang, lang, cfg.projectContext, entry.context ?? null, cfg);
|
|
374
|
+
for (const [cat, translatedText] of Object.entries(forms)) {
|
|
375
|
+
await store.insertPlural({
|
|
376
|
+
sourceText: sourceKey, sourceLang: cfg.sourceLang, targetLang: lang,
|
|
377
|
+
projectContextHash, stringContextHash,
|
|
378
|
+
pluralCategory: cat, translatedText: translatedText,
|
|
379
|
+
model: cfg.backendModel, status: 'translated',
|
|
380
|
+
});
|
|
381
|
+
}
|
|
398
382
|
translated++;
|
|
383
|
+
console.log(` [${done}/${total}] ${lang} translated: ${label}`);
|
|
399
384
|
}
|
|
400
|
-
|
|
385
|
+
catch {
|
|
401
386
|
failed++;
|
|
387
|
+
console.log(` [${done}/${total}] ${lang} failed: ${label}`);
|
|
402
388
|
}
|
|
403
389
|
}
|
|
404
|
-
|
|
405
|
-
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
const stringContextHash = hash(entry.context ?? '');
|
|
393
|
+
const label = (entry.text ?? '').slice(0, 40);
|
|
394
|
+
for (const lang of targetLangs) {
|
|
395
|
+
done++;
|
|
396
|
+
const cached = await store.lookup({
|
|
397
|
+
sourceText: entry.text, sourceLang: cfg.sourceLang, targetLang: lang,
|
|
398
|
+
projectContextHash, stringContextHash,
|
|
399
|
+
});
|
|
400
|
+
if (cached !== null) {
|
|
401
|
+
skipped++;
|
|
402
|
+
console.log(` [${done}/${total}] ${lang} skipped (cached): ${label}`);
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
try {
|
|
406
|
+
const result = await backendTranslate(entry.text, cfg.sourceLang, lang, cfg.projectContext, entry.context ?? null, cfg);
|
|
407
|
+
if (validateTranslation(entry.text, result)) {
|
|
408
|
+
await store.insert({
|
|
409
|
+
sourceText: entry.text, sourceLang: cfg.sourceLang, targetLang: lang,
|
|
410
|
+
projectContextHash, stringContextHash,
|
|
411
|
+
translatedText: result, model: cfg.backendModel, status: 'translated',
|
|
412
|
+
});
|
|
413
|
+
translated++;
|
|
414
|
+
console.log(` [${done}/${total}] ${lang} translated: ${label}`);
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
failed++;
|
|
418
|
+
console.log(` [${done}/${total}] ${lang} failed: ${label}`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
failed++;
|
|
423
|
+
console.log(` [${done}/${total}] ${lang} failed: ${label}`);
|
|
424
|
+
}
|
|
406
425
|
}
|
|
407
426
|
}
|
|
408
427
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
428
|
+
store.close();
|
|
429
|
+
lines.push(`\nTranslated: ${translated} | Skipped: ${skipped} | Failed: ${failed}`);
|
|
430
|
+
} // end if entries.length > 0
|
|
412
431
|
}
|
|
413
432
|
if (!opts.warm && !opts.outputPath) {
|
|
414
433
|
lines.push(`\nRun 'transduck scan --warm --langs DE,ES' to translate all strings.`);
|
package/dist/react/index.js
CHANGED
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -378,6 +378,7 @@ export interface ScanOptions {
|
|
|
378
378
|
export async function runScan(opts: ScanOptions): Promise<string> {
|
|
379
379
|
const cfg = loadConfig(opts.configPath);
|
|
380
380
|
const scanDirs = opts.dirs.length > 0 ? opts.dirs : [process.cwd()];
|
|
381
|
+
console.log('Scanning...');
|
|
381
382
|
const entries = scanDirectory(scanDirs);
|
|
382
383
|
|
|
383
384
|
const regular = entries.filter(e => !e.plural);
|
|
@@ -421,6 +422,9 @@ export async function runScan(opts: ScanOptions): Promise<string> {
|
|
|
421
422
|
|
|
422
423
|
// Warm
|
|
423
424
|
if (opts.warm) {
|
|
425
|
+
if (entries.length === 0) {
|
|
426
|
+
lines.push('\nNothing to warm — no translatable strings found.');
|
|
427
|
+
} else {
|
|
424
428
|
const targetLangs = opts.langs && opts.langs.length > 0
|
|
425
429
|
? opts.langs.map(l => l.toUpperCase())
|
|
426
430
|
: cfg.targetLangs;
|
|
@@ -432,13 +436,17 @@ export async function runScan(opts: ScanOptions): Promise<string> {
|
|
|
432
436
|
let translated = 0;
|
|
433
437
|
let skipped = 0;
|
|
434
438
|
let failed = 0;
|
|
439
|
+
const total = entries.length * targetLangs.length;
|
|
440
|
+
let done = 0;
|
|
435
441
|
|
|
436
442
|
for (const entry of entries) {
|
|
437
443
|
if (entry.plural) {
|
|
438
444
|
const sourceKey = entry.one + '\x00' + entry.other;
|
|
439
445
|
const stringContextHash = hash(entry.context ?? '');
|
|
446
|
+
const label = (entry.one ?? '').slice(0, 40);
|
|
440
447
|
|
|
441
448
|
for (const lang of targetLangs) {
|
|
449
|
+
done++;
|
|
442
450
|
const cachedForms = await store.lookupPlural({
|
|
443
451
|
sourceText: sourceKey, sourceLang: cfg.sourceLang, targetLang: lang,
|
|
444
452
|
projectContextHash, stringContextHash,
|
|
@@ -446,6 +454,7 @@ export async function runScan(opts: ScanOptions): Promise<string> {
|
|
|
446
454
|
|
|
447
455
|
if (Object.keys(cachedForms).length > 0) {
|
|
448
456
|
skipped++;
|
|
457
|
+
console.log(` [${done}/${total}] ${lang} skipped (cached): ${label}`);
|
|
449
458
|
continue;
|
|
450
459
|
}
|
|
451
460
|
|
|
@@ -465,14 +474,18 @@ export async function runScan(opts: ScanOptions): Promise<string> {
|
|
|
465
474
|
});
|
|
466
475
|
}
|
|
467
476
|
translated++;
|
|
477
|
+
console.log(` [${done}/${total}] ${lang} translated: ${label}`);
|
|
468
478
|
} catch {
|
|
469
479
|
failed++;
|
|
480
|
+
console.log(` [${done}/${total}] ${lang} failed: ${label}`);
|
|
470
481
|
}
|
|
471
482
|
}
|
|
472
483
|
} else {
|
|
473
484
|
const stringContextHash = hash(entry.context ?? '');
|
|
485
|
+
const label = (entry.text ?? '').slice(0, 40);
|
|
474
486
|
|
|
475
487
|
for (const lang of targetLangs) {
|
|
488
|
+
done++;
|
|
476
489
|
const cached = await store.lookup({
|
|
477
490
|
sourceText: entry.text!, sourceLang: cfg.sourceLang, targetLang: lang,
|
|
478
491
|
projectContextHash, stringContextHash,
|
|
@@ -480,6 +493,7 @@ export async function runScan(opts: ScanOptions): Promise<string> {
|
|
|
480
493
|
|
|
481
494
|
if (cached !== null) {
|
|
482
495
|
skipped++;
|
|
496
|
+
console.log(` [${done}/${total}] ${lang} skipped (cached): ${label}`);
|
|
483
497
|
continue;
|
|
484
498
|
}
|
|
485
499
|
|
|
@@ -496,11 +510,14 @@ export async function runScan(opts: ScanOptions): Promise<string> {
|
|
|
496
510
|
translatedText: result, model: cfg.backendModel, status: 'translated',
|
|
497
511
|
});
|
|
498
512
|
translated++;
|
|
513
|
+
console.log(` [${done}/${total}] ${lang} translated: ${label}`);
|
|
499
514
|
} else {
|
|
500
515
|
failed++;
|
|
516
|
+
console.log(` [${done}/${total}] ${lang} failed: ${label}`);
|
|
501
517
|
}
|
|
502
518
|
} catch {
|
|
503
519
|
failed++;
|
|
520
|
+
console.log(` [${done}/${total}] ${lang} failed: ${label}`);
|
|
504
521
|
}
|
|
505
522
|
}
|
|
506
523
|
}
|
|
@@ -508,6 +525,7 @@ export async function runScan(opts: ScanOptions): Promise<string> {
|
|
|
508
525
|
|
|
509
526
|
store.close();
|
|
510
527
|
lines.push(`\nTranslated: ${translated} | Skipped: ${skipped} | Failed: ${failed}`);
|
|
528
|
+
} // end if entries.length > 0
|
|
511
529
|
}
|
|
512
530
|
|
|
513
531
|
if (!opts.warm && !opts.outputPath) {
|
package/src/react/index.ts
CHANGED