273 lines
5.3 KiB
JavaScript
273 lines
5.3 KiB
JavaScript
import queryString from "query-string";
|
|
import { fetchPolyfill } from "../libs/fetch";
|
|
import {
|
|
OPT_TRANS_GOOGLE,
|
|
OPT_TRANS_MICROSOFT,
|
|
OPT_TRANS_DEEPL,
|
|
OPT_TRANS_OPENAI,
|
|
OPT_TRANS_CUSTOMIZE,
|
|
OPT_LANGS_SPECIAL,
|
|
PROMPT_PLACE_FROM,
|
|
PROMPT_PLACE_TO,
|
|
KV_SALT_SYNC,
|
|
} from "../config";
|
|
import { tryDetectLang } from "../libs";
|
|
import { sha256 } from "../libs/utils";
|
|
|
|
/**
|
|
* 同步数据
|
|
* @param {*} url
|
|
* @param {*} key
|
|
* @param {*} data
|
|
* @returns
|
|
*/
|
|
export const apiSyncData = async (url, key, data, isBg = false) =>
|
|
fetchPolyfill(url, {
|
|
headers: {
|
|
"Content-type": "application/json",
|
|
Authorization: `Bearer ${await sha256(key, KV_SALT_SYNC)}`,
|
|
},
|
|
method: "POST",
|
|
body: JSON.stringify(data),
|
|
isBg,
|
|
});
|
|
|
|
/**
|
|
* 下载数据
|
|
* @param {*} url
|
|
* @param {*} isBg
|
|
* @returns
|
|
*/
|
|
export const apiFetch = (url, isBg = false) => fetchPolyfill(url, { isBg });
|
|
|
|
/**
|
|
* 谷歌翻译
|
|
* @param {*} text
|
|
* @param {*} to
|
|
* @param {*} from
|
|
* @returns
|
|
*/
|
|
const apiGoogleTranslate = async (
|
|
translator,
|
|
text,
|
|
to,
|
|
from,
|
|
{ url, key, useCache = true }
|
|
) => {
|
|
const params = {
|
|
client: "gtx",
|
|
dt: "t",
|
|
dj: 1,
|
|
ie: "UTF-8",
|
|
sl: from,
|
|
tl: to,
|
|
q: text,
|
|
};
|
|
const input = `${url}?${queryString.stringify(params)}`;
|
|
const res = await fetchPolyfill(input, {
|
|
headers: {
|
|
"Content-type": "application/json",
|
|
},
|
|
useCache,
|
|
usePool: true,
|
|
translator,
|
|
token: key,
|
|
});
|
|
const trText = res.sentences.map((item) => item.trans).join(" ");
|
|
const isSame = to === res.src;
|
|
|
|
return [trText, isSame];
|
|
};
|
|
|
|
/**
|
|
* 微软翻译
|
|
* @param {*} text
|
|
* @param {*} to
|
|
* @param {*} from
|
|
* @returns
|
|
*/
|
|
const apiMicrosoftTranslate = async (
|
|
translator,
|
|
text,
|
|
to,
|
|
from,
|
|
{ url, useCache = true }
|
|
) => {
|
|
const params = {
|
|
from,
|
|
to,
|
|
"api-version": "3.0",
|
|
};
|
|
const input = `${url}?${queryString.stringify(params)}`;
|
|
const res = await fetchPolyfill(input, {
|
|
headers: {
|
|
"Content-type": "application/json",
|
|
},
|
|
method: "POST",
|
|
body: JSON.stringify([{ Text: text }]),
|
|
useCache,
|
|
usePool: true,
|
|
translator,
|
|
});
|
|
const trText = res[0].translations[0].text;
|
|
const isSame = to === res[0].detectedLanguage?.language;
|
|
|
|
return [trText, isSame];
|
|
};
|
|
|
|
/**
|
|
* DeepL翻译
|
|
* @param {*} text
|
|
* @param {*} to
|
|
* @param {*} from
|
|
* @returns
|
|
*/
|
|
const apiDeepLTranslate = async (
|
|
translator,
|
|
text,
|
|
to,
|
|
from,
|
|
{ url, key, useCache = true }
|
|
) => {
|
|
const data = {
|
|
text: [text],
|
|
target_lang: to,
|
|
split_sentences: "0",
|
|
};
|
|
if (from) {
|
|
data.source_lang = from;
|
|
}
|
|
const res = await fetchPolyfill(url, {
|
|
headers: {
|
|
"Content-type": "application/json",
|
|
},
|
|
method: "POST",
|
|
body: JSON.stringify(data),
|
|
useCache,
|
|
usePool: true,
|
|
translator,
|
|
token: key,
|
|
});
|
|
const trText = res.translations.map((item) => item.text).join(" ");
|
|
const isSame = to === res.translations[0].detected_source_language;
|
|
|
|
return [trText, isSame];
|
|
};
|
|
|
|
/**
|
|
* OpenAI 翻译
|
|
* @param {*} text
|
|
* @param {*} to
|
|
* @param {*} from
|
|
* @returns
|
|
*/
|
|
const apiOpenaiTranslate = async (
|
|
translator,
|
|
text,
|
|
to,
|
|
from,
|
|
{ url, key, model, prompt, useCache = true }
|
|
) => {
|
|
prompt = prompt
|
|
.replaceAll(PROMPT_PLACE_FROM, from)
|
|
.replaceAll(PROMPT_PLACE_TO, to);
|
|
const res = await fetchPolyfill(url, {
|
|
headers: {
|
|
"Content-type": "application/json",
|
|
},
|
|
method: "POST",
|
|
body: JSON.stringify({
|
|
model: model,
|
|
messages: [
|
|
{
|
|
role: "system",
|
|
content: prompt,
|
|
},
|
|
{
|
|
role: "user",
|
|
content: text,
|
|
},
|
|
],
|
|
temperature: 0,
|
|
max_tokens: 256,
|
|
}),
|
|
useCache,
|
|
usePool: true,
|
|
translator,
|
|
token: key,
|
|
});
|
|
const trText = res?.choices?.[0].message.content;
|
|
const sLang = await tryDetectLang(text);
|
|
const tLang = await tryDetectLang(trText);
|
|
const isSame = text === trText || (sLang && tLang && sLang === tLang);
|
|
|
|
return [trText, isSame];
|
|
};
|
|
|
|
/**
|
|
* 自定义接口 翻译
|
|
* @param {*} text
|
|
* @param {*} to
|
|
* @param {*} from
|
|
* @returns
|
|
*/
|
|
const apiCustomTranslate = async (
|
|
translator,
|
|
text,
|
|
to,
|
|
from,
|
|
{ url, key, useCache = true }
|
|
) => {
|
|
const res = await fetchPolyfill(url, {
|
|
headers: {
|
|
"Content-type": "application/json",
|
|
},
|
|
method: "POST",
|
|
body: JSON.stringify({
|
|
text,
|
|
from,
|
|
to,
|
|
}),
|
|
useCache,
|
|
usePool: true,
|
|
translator,
|
|
token: key,
|
|
});
|
|
const trText = res.text;
|
|
const isSame = to === res.from;
|
|
|
|
return [trText, isSame];
|
|
};
|
|
|
|
/**
|
|
* 统一翻译接口
|
|
* @param {*} param0
|
|
* @returns
|
|
*/
|
|
export const apiTranslate = ({
|
|
translator,
|
|
text,
|
|
fromLang,
|
|
toLang,
|
|
apiSetting,
|
|
}) => {
|
|
const from = OPT_LANGS_SPECIAL[translator]?.get(fromLang) ?? fromLang;
|
|
const to = OPT_LANGS_SPECIAL[translator]?.get(toLang) ?? toLang;
|
|
const callApi = (api) => api(translator, text, to, from, apiSetting);
|
|
|
|
switch (translator) {
|
|
case OPT_TRANS_GOOGLE:
|
|
return callApi(apiGoogleTranslate);
|
|
case OPT_TRANS_MICROSOFT:
|
|
return callApi(apiMicrosoftTranslate);
|
|
case OPT_TRANS_DEEPL:
|
|
return callApi(apiDeepLTranslate);
|
|
case OPT_TRANS_OPENAI:
|
|
return callApi(apiOpenaiTranslate);
|
|
case OPT_TRANS_CUSTOMIZE:
|
|
return callApi(apiCustomTranslate);
|
|
default:
|
|
return ["", false];
|
|
}
|
|
};
|