Files
kiss-translator/src/apis/index.js

369 lines
8.5 KiB
JavaScript
Raw Normal View History

2023-07-20 13:45:41 +08:00
import queryString from "query-string";
import { fetchData } from "../libs/fetch";
2023-07-20 13:45:41 +08:00
import {
OPT_TRANS_GOOGLE,
2025-07-02 13:38:30 +08:00
OPT_TRANS_GOOGLE_2,
2023-07-20 13:45:41 +08:00
OPT_TRANS_MICROSOFT,
2023-09-02 16:57:09 +08:00
OPT_TRANS_DEEPL,
2023-10-20 17:44:48 +08:00
OPT_TRANS_DEEPLFREE,
2023-10-17 11:33:26 +08:00
OPT_TRANS_DEEPLX,
2024-04-12 11:31:01 +08:00
OPT_TRANS_NIUTRANS,
2023-10-20 17:44:48 +08:00
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
2025-06-30 21:34:37 +08:00
OPT_TRANS_VOLCENGINE,
2023-07-20 13:45:41 +08:00
OPT_TRANS_OPENAI,
2024-04-28 16:58:09 +08:00
OPT_TRANS_OPENAI_2,
OPT_TRANS_OPENAI_3,
2023-12-21 14:15:14 +08:00
OPT_TRANS_GEMINI,
2025-07-02 21:54:18 +08:00
OPT_TRANS_GEMINI_2,
2024-09-23 18:22:19 +08:00
OPT_TRANS_CLAUDE,
2023-10-26 11:13:50 +08:00
OPT_TRANS_CLOUDFLAREAI,
2024-04-28 21:43:20 +08:00
OPT_TRANS_OLLAMA,
OPT_TRANS_OLLAMA_2,
OPT_TRANS_OLLAMA_3,
OPT_TRANS_OPENROUTER,
2023-09-06 00:25:46 +08:00
OPT_TRANS_CUSTOMIZE,
2024-04-10 13:37:16 +08:00
OPT_TRANS_CUSTOMIZE_2,
OPT_TRANS_CUSTOMIZE_3,
OPT_TRANS_CUSTOMIZE_4,
OPT_TRANS_CUSTOMIZE_5,
2023-10-20 17:44:48 +08:00
URL_CACHE_TRAN,
2023-08-20 23:30:08 +08:00
KV_SALT_SYNC,
2024-05-22 23:33:30 +08:00
URL_GOOGLE_TRAN,
URL_MICROSOFT_LANGDETECT,
2023-10-10 18:03:05 +08:00
URL_BAIDU_LANGDETECT,
2024-03-19 11:48:30 +08:00
URL_BAIDU_SUGGEST,
2024-03-25 18:14:12 +08:00
URL_BAIDU_TTS,
2023-10-10 18:03:05 +08:00
OPT_LANGS_BAIDU,
URL_TENCENT_TRANSMART,
OPT_LANGS_TENCENT,
OPT_LANGS_SPECIAL,
2024-05-22 23:33:30 +08:00
OPT_LANGS_MICROSOFT,
2023-07-20 13:45:41 +08:00
} from "../config";
2023-08-20 23:30:08 +08:00
import { sha256 } from "../libs/utils";
2024-05-12 16:10:11 +08:00
import interpreter from "../libs/interpreter";
2024-05-22 23:33:30 +08:00
import { msAuth } from "../libs/auth";
2025-07-03 18:08:49 +08:00
import { kissLog } from "../libs/log";
2023-07-20 13:45:41 +08:00
2023-07-31 15:08:51 +08:00
/**
* 同步数据
* @param {*} url
* @param {*} key
* @param {*} data
* @returns
*/
2023-09-20 17:47:23 +08:00
export const apiSyncData = async (url, key, data) =>
fetchData(url, {
2023-08-21 23:46:42 +08:00
headers: {
"Content-type": "application/json",
Authorization: `Bearer ${await sha256(key, KV_SALT_SYNC)}`,
2023-07-31 15:08:51 +08:00
},
2023-08-21 23:46:42 +08:00
method: "POST",
body: JSON.stringify(data),
});
2023-07-31 15:08:51 +08:00
2023-08-30 18:05:37 +08:00
/**
2023-09-08 21:41:32 +08:00
* 下载数据
2023-08-30 18:05:37 +08:00
* @param {*} url
* @returns
*/
export const apiFetch = (url) => fetchData(url);
2023-08-30 18:05:37 +08:00
2024-05-22 23:33:30 +08:00
/**
* Google语言识别
* @param {*} text
* @returns
*/
export const apiGoogleLangdetect = async (text) => {
const params = {
client: "gtx",
dt: "t",
dj: 1,
ie: "UTF-8",
sl: "auto",
tl: "zh-CN",
q: text,
};
const input = `${URL_GOOGLE_TRAN}?${queryString.stringify(params)}`;
const res = await fetchData(input, {
headers: {
"Content-type": "application/json",
},
useCache: true,
});
return res.src;
};
/**
* Microsoft语言识别
* @param {*} text
* @returns
*/
export const apiMicrosoftLangdetect = async (text) => {
const [token] = await msAuth();
const res = await fetchData(URL_MICROSOFT_LANGDETECT, {
headers: {
"Content-type": "application/json",
Authorization: `Bearer ${token}`,
},
method: "POST",
body: JSON.stringify([{ Text: text }]),
useCache: true,
});
return OPT_LANGS_MICROSOFT.get(res[0].language) ?? res[0].language;
};
2023-07-20 13:45:41 +08:00
/**
* 百度语言识别
2023-07-31 03:10:09 +08:00
* @param {*} text
* @returns
2023-07-20 13:45:41 +08:00
*/
export const apiBaiduLangdetect = async (text) => {
const res = await fetchData(URL_BAIDU_LANGDETECT, {
headers: {
"Content-type": "application/json",
2023-07-20 13:45:41 +08:00
},
method: "POST",
body: JSON.stringify({
query: text,
}),
useCache: true,
2023-09-06 00:25:46 +08:00
});
2023-09-06 14:57:02 +08:00
if (res.error === 0) {
return OPT_LANGS_BAIDU.get(res.lan) ?? res.lan;
}
return "";
2023-09-06 00:25:46 +08:00
};
2024-03-19 11:48:30 +08:00
/**
* 百度翻译建议
* @param {*} text
* @returns
*/
export const apiBaiduSuggest = async (text) => {
const res = await fetchData(URL_BAIDU_SUGGEST, {
2024-03-19 11:48:30 +08:00
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify({
kw: text,
}),
useCache: true,
});
if (res.errno === 0) {
return res.data;
}
return [];
};
2024-03-25 18:14:12 +08:00
/**
* 百度语音
* @param {*} text
* @param {*} lan
* @param {*} spd
* @returns
*/
export const apiBaiduTTS = (text, lan = "uk", spd = 3) => {
const url = `${URL_BAIDU_TTS}?${queryString.stringify({ lan, text, spd })}`;
return fetchData(url, {
2024-03-25 21:00:39 +08:00
useCache: false, // 为避免缓存过快增长,禁用缓存语音数据
});
2024-03-25 18:14:12 +08:00
};
2023-09-06 00:25:46 +08:00
/**
* 腾讯语言识别
2023-09-06 00:25:46 +08:00
* @param {*} text
* @returns
*/
export const apiTencentLangdetect = async (text) => {
const body = JSON.stringify({
header: {
fn: "text_analysis",
2023-09-06 00:25:46 +08:00
},
text,
});
2023-07-20 13:45:41 +08:00
const res = await fetchData(URL_TENCENT_TRANSMART, {
2023-10-10 18:03:05 +08:00
headers: {
"Content-type": "application/json",
},
method: "POST",
body,
2023-10-10 18:03:05 +08:00
useCache: true,
});
return OPT_LANGS_TENCENT.get(res.language) ?? res.language;
2023-10-10 18:03:05 +08:00
};
2023-07-20 13:45:41 +08:00
/**
* 统一翻译接口
* @param {*} param0
* @returns
*/
2023-10-20 17:44:48 +08:00
export const apiTranslate = async ({
2023-08-30 18:05:37 +08:00
translator,
2023-09-06 14:57:02 +08:00
text,
2023-08-30 18:05:37 +08:00
fromLang,
toLang,
2023-10-20 17:44:48 +08:00
apiSetting = {},
useCache = true,
usePool = true,
2023-08-30 18:05:37 +08:00
}) => {
2023-10-20 17:44:48 +08:00
let trText = "";
let isSame = false;
2023-10-13 10:48:01 +08:00
2023-11-07 17:52:33 +08:00
if (!text) {
return [trText, true];
}
const from =
OPT_LANGS_SPECIAL[translator].get(fromLang) ??
OPT_LANGS_SPECIAL[translator].get("auto");
const to = OPT_LANGS_SPECIAL[translator].get(toLang);
2023-11-07 17:52:33 +08:00
if (!to) {
2025-07-03 18:08:49 +08:00
kissLog(`target lang: ${toLang} not support`, "translate");
return [trText, isSame];
}
2024-01-18 15:26:37 +08:00
// 版本号一/二位升级,旧缓存失效
const [v1, v2] = process.env.REACT_APP_VERSION.split(".");
const cacheOpts = {
2023-10-20 17:44:48 +08:00
translator,
text,
fromLang,
toLang,
2024-01-18 15:26:37 +08:00
version: [v1, v2].join("."),
2023-10-20 17:44:48 +08:00
};
2023-10-13 10:48:01 +08:00
const transOpts = {
translator,
text,
from,
to,
};
const res = await fetchData(
`${URL_CACHE_TRAN}?${queryString.stringify(cacheOpts)}`,
2023-10-20 17:44:48 +08:00
{
useCache,
usePool,
transOpts,
apiSetting,
}
);
2023-07-20 13:45:41 +08:00
2023-09-06 14:57:02 +08:00
switch (translator) {
2025-06-26 11:13:51 +08:00
case OPT_TRANS_GOOGLE:
trText = res.sentences.map((item) => item.trans).join(" ");
isSame = to === res.src;
break;
2025-07-02 13:38:30 +08:00
case OPT_TRANS_GOOGLE_2:
2025-07-02 21:54:18 +08:00
trText = res?.[0]?.[0] || "";
isSame = to === res.src;
2023-10-20 17:44:48 +08:00
break;
2023-09-06 14:57:02 +08:00
case OPT_TRANS_MICROSOFT:
2024-01-19 16:02:53 +08:00
trText = res
.map((item) => item.translations.map((item) => item.text).join(" "))
.join(" ");
isSame = text === trText;
2023-10-20 17:44:48 +08:00
break;
2023-09-06 14:57:02 +08:00
case OPT_TRANS_DEEPL:
trText = res.translations.map((item) => item.text).join(" ");
isSame = to === res.translations[0].detected_source_language;
2023-10-20 17:44:48 +08:00
break;
case OPT_TRANS_DEEPLFREE:
trText = res.result?.texts.map((item) => item.text).join(" ");
isSame = to === res.result?.lang;
2023-10-20 17:44:48 +08:00
break;
2023-10-17 11:33:26 +08:00
case OPT_TRANS_DEEPLX:
trText = res.data;
isSame = to === res.source_lang;
2023-10-20 17:44:48 +08:00
break;
2024-04-12 11:31:01 +08:00
case OPT_TRANS_NIUTRANS:
const json = JSON.parse(res);
if (json.error_msg) {
throw new Error(json.error_msg);
}
trText = json.tgt_text;
isSame = to === json.from;
break;
2023-10-20 17:44:48 +08:00
case OPT_TRANS_BAIDU:
2024-01-18 15:26:37 +08:00
// trText = res.trans_result?.data.map((item) => item.dst).join(" ");
// isSame = res.trans_result?.to === res.trans_result?.from;
if (res.type === 1) {
trText = Object.keys(JSON.parse(res.result).content[0].mean[0].cont)[0];
isSame = to === res.from;
} else if (res.type === 2) {
2024-01-19 16:02:53 +08:00
trText = res.data.map((item) => item.dst).join(" ");
2024-01-18 15:26:37 +08:00
isSame = to === res.from;
}
2023-10-20 17:44:48 +08:00
break;
case OPT_TRANS_TENCENT:
2025-06-27 20:03:58 +08:00
trText = res?.auto_translation?.[0];
2023-10-20 17:44:48 +08:00
isSame = text === trText;
break;
2025-06-30 21:34:37 +08:00
case OPT_TRANS_VOLCENGINE:
trText = res?.translation || "";
isSame = to === res?.detected_language;
break;
2023-09-06 14:57:02 +08:00
case OPT_TRANS_OPENAI:
2024-04-28 16:58:09 +08:00
case OPT_TRANS_OPENAI_2:
case OPT_TRANS_OPENAI_3:
2025-07-02 21:54:18 +08:00
case OPT_TRANS_GEMINI_2:
case OPT_TRANS_OPENROUTER:
2024-01-19 16:02:53 +08:00
trText = res?.choices?.map((item) => item.message.content).join(" ");
isSame = text === trText;
2023-10-20 17:44:48 +08:00
break;
2023-12-21 14:15:14 +08:00
case OPT_TRANS_GEMINI:
2024-01-19 16:02:53 +08:00
trText = res?.candidates
2024-02-21 15:47:14 +08:00
?.map((item) => item.content?.parts.map((item) => item.text).join(" "))
2024-01-19 16:02:53 +08:00
.join(" ");
2023-12-21 14:15:14 +08:00
isSame = text === trText;
break;
2024-09-23 18:22:19 +08:00
case OPT_TRANS_CLAUDE:
trText = res?.content?.map((item) => item.text).join(" ");
isSame = text === trText;
break;
2023-10-26 11:13:50 +08:00
case OPT_TRANS_CLOUDFLAREAI:
trText = res?.result?.translated_text;
isSame = text === trText;
break;
2024-04-28 21:43:20 +08:00
case OPT_TRANS_OLLAMA:
case OPT_TRANS_OLLAMA_2:
case OPT_TRANS_OLLAMA_3:
2025-06-27 16:33:30 +08:00
const { thinkIgnore = "" } = apiSetting;
2025-07-02 21:54:18 +08:00
const deepModels = thinkIgnore.split(",").filter((model) => model.trim());
if (deepModels.some((model) => res?.model?.startsWith(model))) {
trText = res?.response.replace(/<think>[\s\S]*<\/think>/i, "");
} else {
trText = res?.response;
}
2024-04-28 21:43:20 +08:00
isSame = text === trText;
break;
2023-09-06 14:57:02 +08:00
case OPT_TRANS_CUSTOMIZE:
2024-04-10 13:37:16 +08:00
case OPT_TRANS_CUSTOMIZE_2:
case OPT_TRANS_CUSTOMIZE_3:
case OPT_TRANS_CUSTOMIZE_4:
case OPT_TRANS_CUSTOMIZE_5:
2024-05-12 16:10:11 +08:00
const { resHook } = apiSetting;
if (resHook?.trim()) {
interpreter.run(`exports.resHook = ${resHook}`);
[trText, isSame] = interpreter.exports.resHook(res, text, from, to);
} else {
trText = res.text;
isSame = to === res.from;
2024-04-17 22:35:12 +08:00
}
2023-10-20 17:44:48 +08:00
break;
2023-09-06 14:57:02 +08:00
default:
2023-07-20 13:45:41 +08:00
}
2023-10-20 17:44:48 +08:00
return [trText, isSame, res];
2023-07-20 13:45:41 +08:00
};