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

296 lines
6.3 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 {
2023-10-20 17:44:48 +08:00
URL_CACHE_TRAN,
2023-08-20 23:30:08 +08:00
KV_SALT_SYNC,
2023-10-10 18:03:05 +08:00
OPT_LANGS_BAIDU,
OPT_LANGS_TENCENT,
OPT_LANGS_SPECIAL,
2024-05-22 23:33:30 +08:00
OPT_LANGS_MICROSOFT,
API_SPE_TYPES,
DEFAULT_API_SETTING,
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-22 23:33:30 +08:00
import { msAuth } from "../libs/auth";
2025-07-03 18:08:49 +08:00
import { kissLog } from "../libs/log";
2025-09-03 13:05:41 +08:00
import { handleTranslate } from "./trans";
import { getHttpCachePolyfill, putHttpCachePolyfill } from "../libs/cache";
import { getBatchQueue } from "../libs/batchQueue";
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,
};
2025-09-01 18:56:48 +08:00
const input = `https://translate.googleapis.com/translate_a/single?${queryString.stringify(params)}`;
const init = {
2024-05-22 23:33:30 +08:00
headers: {
"Content-type": "application/json",
},
};
const res = await fetchData(input, init, { useCache: true });
if (res?.src) {
await putHttpCachePolyfill(input, init, res);
return res.src;
}
2024-05-22 23:33:30 +08:00
return "";
2024-05-22 23:33:30 +08:00
};
/**
* Microsoft语言识别
* @param {*} text
* @returns
*/
export const apiMicrosoftLangdetect = async (text) => {
const [token] = await msAuth();
const input =
"https://api-edge.cognitive.microsofttranslator.com/detect?api-version=3.0";
const init = {
2024-05-22 23:33:30 +08:00
headers: {
"Content-type": "application/json",
Authorization: `Bearer ${token}`,
},
method: "POST",
body: JSON.stringify([{ Text: text }]),
};
const res = await fetchData(input, init, {
2024-05-22 23:33:30 +08:00
useCache: true,
});
if (res[0].language) {
await putHttpCachePolyfill(input, init, res);
return OPT_LANGS_MICROSOFT.get(res[0].language) ?? res[0].language;
}
return "";
2024-05-22 23:33:30 +08:00
};
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 input = "https://fanyi.baidu.com/langdetect";
const init = {
headers: {
"Content-type": "application/json",
2023-07-20 13:45:41 +08:00
},
method: "POST",
body: JSON.stringify({
query: text,
}),
};
const res = await fetchData(input, init, { useCache: true });
2023-09-06 14:57:02 +08:00
if (res.error === 0) {
await putHttpCachePolyfill(input, init, res);
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 input = "https://fanyi.baidu.com/sug";
const init = {
2024-03-19 11:48:30 +08:00
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify({
kw: text,
}),
};
const res = await fetchData(input, init, { useCache: true });
2024-03-19 11:48:30 +08:00
if (res.errno === 0) {
await putHttpCachePolyfill(input, init, res);
2024-03-19 11:48:30 +08:00
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 input = `https://fanyi.baidu.com/gettts?${queryString.stringify({ lan, text, spd })}`;
return fetchData(input);
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 input = "https://transmart.qq.com/api/imt";
const body = JSON.stringify({
header: {
fn: "text_analysis",
2023-09-06 00:25:46 +08:00
},
text,
});
const init = {
2023-10-10 18:03:05 +08:00
headers: {
"Content-type": "application/json",
},
method: "POST",
body,
};
const res = await fetchData(input, init, { useCache: true });
if (res.language) {
await putHttpCachePolyfill(input, init, res);
return OPT_LANGS_TENCENT.get(res.language) ?? res.language;
}
2023-10-10 18:03:05 +08:00
return "";
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-09-06 14:57:02 +08:00
text,
2023-08-30 18:05:37 +08:00
fromLang,
toLang,
apiSetting = DEFAULT_API_SETTING,
docInfo = {},
2023-10-20 17:44:48 +08:00
useCache = true,
usePool = true,
2023-08-30 18:05:37 +08:00
}) => {
2023-11-07 17:52:33 +08:00
if (!text) {
return ["", false];
2023-11-07 17:52:33 +08:00
}
const { apiType, apiSlug, useBatchFetch } = apiSetting;
2025-09-25 23:08:39 +08:00
const langMap = OPT_LANGS_SPECIAL[apiType];
const from = langMap.get(fromLang) ?? langMap.get("auto");
const to = langMap.get(toLang);
2023-11-07 17:52:33 +08:00
if (!to) {
kissLog(`target lang: ${toLang} not support`);
return ["", false];
}
// todo: 优化缓存失效因素
const [v1, v2] = process.env.REACT_APP_VERSION.split(".");
const cacheOpts = {
apiSlug,
text,
fromLang,
toLang,
version: [v1, v2].join("."),
};
const cacheInput = `${URL_CACHE_TRAN}?${queryString.stringify(cacheOpts)}`;
// 查询缓存数据
if (useCache) {
const cache = (await getHttpCachePolyfill(cacheInput)) || {};
if (cache.trText) {
return [cache.trText, cache.isSame];
}
}
2023-10-13 10:48:01 +08:00
// 请求接口数据
let trText = "";
let srLang = "";
if (useBatchFetch && API_SPE_TYPES.batch.has(apiType)) {
const queue = getBatchQueue({
from,
to,
2025-09-25 23:08:39 +08:00
fromLang,
toLang,
langMap,
docInfo,
apiSetting,
usePool,
taskFn: handleTranslate,
});
const tranlation = await queue.addTask({ text });
if (Array.isArray(tranlation)) {
[trText, srLang = ""] = tranlation;
2025-09-25 23:08:39 +08:00
} else if (typeof tranlation === "string") {
trText = tranlation;
}
} else {
2025-09-03 13:05:41 +08:00
const translations = await handleTranslate({
texts: [text],
from,
to,
2025-09-25 23:08:39 +08:00
fromLang,
toLang,
langMap,
docInfo,
apiSetting,
usePool,
});
2025-09-25 23:08:39 +08:00
if (Array.isArray(translations)) {
if (Array.isArray(translations[0])) {
[trText, srLang = ""] = translations[0];
} else {
[trText, srLang = ""] = translations;
}
}
}
2025-09-25 23:08:39 +08:00
// const isSame = srLang && (to.includes(srLang) || srLang.includes(to));
const isSame = srLang && srLang.slice(0, 2) === to.slice(0, 2);
2023-07-20 13:45:41 +08:00
// 插入缓存
if (useCache && trText) {
putHttpCachePolyfill(cacheInput, null, { trText, isSame, srLang });
2023-07-20 13:45:41 +08:00
}
2023-10-20 17:44:48 +08:00
return [trText, isSame];
2023-07-20 13:45:41 +08:00
};