i18n-helper-babel
Version:
i18n 命令行工具。一键包裹,提取,翻译,统计。支持网页截图,翻译词条检测
233 lines (219 loc) • 6.45 kB
text/typescript
import path from 'path';
import fs from 'fs';
import fse from 'fs-extra';
import * as tencentCloud from 'tencentcloud-sdk-nodejs';
import { t } from '../i18n';
import Logger from '../util/logger';
import { formatJSON } from '../util/helper';
import { iI18nConf, TransType, iActionResult } from '../types';
/**
* 从翻译词条数据源翻译
* @param targetLang 目标翻译语言
* @param unTranslateKeys 未翻译词条
* @param i18nConf i18n 配置对象
* @param source 目标翻译原
* @returns 实际翻译词条数
*/
const translateFromSourceFile = (
targetLang: string,
unTranslateKeys: string[],
i18nConf: iI18nConf,
source: Record<string, string>,
) => {
let transCount = 0;
const { targetTransDir, targetTransFile } = i18nConf;
// 人工翻译源文件
const targetTranslateFile = `${path.resolve(
targetTransDir,
targetLang,
targetTransFile,
)}`;
const isTargetTranslateFileExited = fs.existsSync(targetTranslateFile);
if (isTargetTranslateFileExited) {
const target =
fse.readJSONSync(targetTranslateFile, { throws: false }) || {};
unTranslateKeys.map((key) => {
const transValue = typeof target[key] === 'undefined' ? '' : target[key];
if (transValue) {
transCount += 1;
}
source[key] = transValue;
});
} else {
Logger.error(
t(
'【翻译错误】翻译文件{{targetTranslateFile}}不存在 请检查命令行【translate】后的语言 或 i18n.config.json 中配置',
{
targetTranslateFile,
},
),
);
}
return transCount;
};
/**
* 机器翻译(腾讯翻译君)
* @param targetLang 目标翻译语言
* @param unTranslateKeys 未翻译词条
* @param i18nConf i18n 配置对象
* @param source 目标翻译原
* @returns 实际翻译词条数
*/
const translateFromTMT = async (
targetLang: string,
unTranslateKeys: string[],
i18nConf: iI18nConf,
source: Record<string, string>,
) => {
const { secretId, secretKey } = i18nConf;
if (!secretId && !secretKey) {
Logger.error(
t(
'【翻译错误】secretId或secretKey不存在 请检查i18n.config.json 中【secretId】或【secretKey】配置',
),
);
return -1;
}
let transCount = 0;
const TMTClient = tencentCloud.tmt.v20180321.Client;
const clientConfig = {
// 腾讯云认证信息
credential: {
secretId,
secretKey,
},
// 产品地域
region: 'ap-shanghai',
// 可选配置实例
profile: {
signMethod: 'HmacSHA256',
httpProfile: {
reqMethod: 'POST',
reqTimeout: 30,
},
},
};
// 实例化要请TMT的client对象
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
const client = new TMTClient(clientConfig);
const { TargetTextList } = await client.TextTranslateBatch({
// 自动识别(识别为一种语言)
Source: 'auto',
// 目标语言
Target: targetLang,
ProjectId: 0,
// 待翻译词条
SourceTextList: unTranslateKeys,
});
const transObj: Record<string, string> = {};
if (TargetTextList) {
for (let i = 0; i < unTranslateKeys.length; i += 1) {
transObj[unTranslateKeys[i]] = TargetTextList[i];
}
}
unTranslateKeys.map((key) => {
const transValue =
typeof transObj[key] === 'undefined' ? '' : transObj[key];
if (transValue) {
transCount += 1;
}
source[key] = transValue;
});
return transCount;
};
/**
* 翻译词条
* @param languages 目标翻译语言列表
* @param i18nConf i18n 配置对象
* @param transType 翻译方式
* @returns 翻译结果信息
*/
const translate = async (
languages: string | string[],
i18nConf: iI18nConf,
transType: TransType,
): Promise<iActionResult> => {
const transResult: iActionResult = { TRANSLATE_FILE: 0 };
const tranTypeWording =
transType === TransType.SourceFile
? t('【翻译 - 从源文件翻译】')
: t('【翻译 - TMT机器翻译】');
const { localeDir, transFileName, transFileExt } = i18nConf;
const curLanguages =
typeof languages === 'string' ? languages.split(',') : languages;
await Promise.all(
curLanguages.map(async (lang) => {
// 翻译词条数
let transCount = 0;
// 待翻译文件
const transFile = `${path.resolve(
localeDir,
lang,
transFileName,
)}.${transFileExt}`;
const isTransFilesExited = fs.existsSync(transFile);
if (isTransFilesExited) {
const source = fse.readJSONSync(transFile);
const unTranslatedWord = Object.fromEntries(
Object.entries(source).filter(([key, value]) => value === ''),
);
const unTransKeys = Object.keys(unTranslatedWord);
// 有词条需要翻译
if (unTransKeys.length > 0) {
if (transType === TransType.SourceFile) {
transCount = translateFromSourceFile(
lang,
unTransKeys,
i18nConf,
source,
);
} else {
transCount = await translateFromTMT(
lang,
unTransKeys,
i18nConf,
source,
);
}
// 翻译词条数大于 0
if (transCount > 0) {
transResult[lang] = transCount;
fse.outputFileSync(transFile, formatJSON(source));
Logger.success(
t('{{tranTypeWording}}【{{lang}}】已完成!', {
tranTypeWording,
lang,
}),
);
} else if (transCount === 0) {
Logger.warning(
t('{{tranTypeWording}}【{{lang}}】本次无词条被翻译!', {
tranTypeWording,
lang,
}),
);
}
} else {
Logger.warning(
t('{{tranTypeWording}}【{{lang}}】本次没有词条需要翻译!', {
tranTypeWording,
lang,
}),
);
}
} else {
Logger.error(
t(
'【翻译错误】待翻译文件{{transFile}}不存在 请检查命令行【translate】后的语言 或 i18n.config.json 中【languages】配置',
{
transFile,
},
),
);
}
}),
);
return transResult;
};
export default translate;