Files
kiss-translator/src/apis/index.js
Gabe Yuan c46fe7d1c6 dev...
2023-08-30 18:05:37 +08:00

180 lines
4.0 KiB
JavaScript

import queryString from "query-string";
import { fetchPolyfill } from "../libs/fetch";
import {
GLOBAL_KEY,
OPT_TRANS_GOOGLE,
OPT_TRANS_MICROSOFT,
OPT_TRANS_OPENAI,
URL_MICROSOFT_TRANS,
OPT_LANGS_SPECIAL,
PROMPT_PLACE_FROM,
PROMPT_PLACE_TO,
KV_SALT_SYNC,
} from "../config";
import { detectLang } from "../libs/browser";
import { sha256 } from "../libs/utils";
import { checkRules } from "../libs/rules";
/**
* 同步数据
* @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 apiFetchRules = async (url, isBg = false) => {
const res = await fetchPolyfill(url, { isBg });
const rules = checkRules(res).filter(
(rule) => rule.pattern.replaceAll(GLOBAL_KEY, "") !== ""
);
return rules;
};
/**
* 谷歌翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
const apiGoogleTranslate = async (translator, text, to, from, setting) => {
const { googleUrl } = setting;
const params = {
client: "gtx",
dt: "t",
dj: 1,
ie: "UTF-8",
sl: from,
tl: to,
q: text,
};
const input = `${googleUrl}?${queryString.stringify(params)}`;
return fetchPolyfill(input, {
headers: {
"Content-type": "application/json",
},
useCache: true,
usePool: true,
translator,
});
};
/**
* 微软翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
const apiMicrosoftTranslate = (translator, text, to, from) => {
const params = {
from,
to,
"api-version": "3.0",
};
const input = `${URL_MICROSOFT_TRANS}?${queryString.stringify(params)}`;
return fetchPolyfill(input, {
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify([{ Text: text }]),
useCache: true,
usePool: true,
translator,
});
};
/**
* OpenAI 翻译
* @param {*} text
* @param {*} to
* @param {*} from
* @returns
*/
const apiOpenaiTranslate = async (translator, text, to, from, setting) => {
const { openaiUrl, openaiKey, openaiModel, openaiPrompt } = setting;
let prompt = openaiPrompt
.replaceAll(PROMPT_PLACE_FROM, from)
.replaceAll(PROMPT_PLACE_TO, to);
return fetchPolyfill(openaiUrl, {
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify({
model: openaiModel,
messages: [
{
role: "system",
content: prompt,
},
{
role: "user",
content: text,
},
],
temperature: 0,
max_tokens: 256,
}),
useCache: true,
usePool: true,
translator,
token: openaiKey,
});
};
/**
* 统一翻译接口
* @param {*} param0
* @returns
*/
export const apiTranslate = async ({
translator,
q,
fromLang,
toLang,
setting,
}) => {
let trText = "";
let isSame = false;
let from = OPT_LANGS_SPECIAL?.[translator]?.get(fromLang) ?? fromLang;
let to = OPT_LANGS_SPECIAL?.[translator]?.get(toLang) ?? toLang;
if (translator === OPT_TRANS_GOOGLE) {
const res = await apiGoogleTranslate(translator, q, to, from, setting);
trText = res.sentences.map((item) => item.trans).join(" ");
isSame = to === res.src;
} else if (translator === OPT_TRANS_MICROSOFT) {
const res = await apiMicrosoftTranslate(translator, q, to, from);
trText = res[0].translations[0].text;
isSame = to === res[0].detectedLanguage.language;
} else if (translator === OPT_TRANS_OPENAI) {
const res = await apiOpenaiTranslate(translator, q, to, from, setting);
trText = res?.choices?.[0].message.content;
const sLang = await detectLang(q);
const tLang = await detectLang(trText);
isSame = q === trText || (sLang && tLang && sLang === tLang);
}
return [trText, isSame];
};