diff --git a/src/apis/baidu.js b/src/apis/baidu.js new file mode 100644 index 0000000..4eab693 --- /dev/null +++ b/src/apis/baidu.js @@ -0,0 +1,257 @@ +import queryString from "query-string"; +import { fetchPolyfill } from "../libs/fetch"; +import { getBdauth, setBdauth } from "../libs/storage"; +import { URL_BAIDU_WEB, URL_BAIDU_TRAN } from "../config"; + +/* eslint-disable */ +function n(t, e) { + for (var n = 0; n < e.length - 2; n += 3) { + var r = e.charAt(n + 2); + (r = "a" <= r ? r.charCodeAt(0) - 87 : Number(r)), + (r = "+" === e.charAt(n + 1) ? t >>> r : t << r), + (t = "+" === e.charAt(n) ? (t + r) & 4294967295 : t ^ r); + } + return t; +} + +function e(t, e) { + (null == e || e > t.length) && (e = t.length); + for (var n = 0, r = new Array(e); n < e; n++) r[n] = t[n]; + return r; +} + +/* eslint-disable */ +function getSign(t, gtk, r = null) { + var o, + i = t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g); + if (null === i) { + var a = t.length; + a > 30 && + (t = "" + .concat(t.substr(0, 10)) + .concat(t.substr(Math.floor(a / 2) - 5, 10)) + .concat(t.substr(-10, 10))); + } else { + for ( + var s = t.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), + c = 0, + u = s.length, + l = []; + c < u; + c++ + ) + "" !== s[c] && + l.push.apply( + l, + (function (t) { + if (Array.isArray(t)) return e(t); + })((o = s[c].split(""))) || + (function (t) { + if ( + ("undefined" != typeof Symbol && null != t[Symbol.iterator]) || + null != t["@@iterator"] + ) + return Array.from(t); + })(o) || + (function (t, n) { + if (t) { + if ("string" == typeof t) return e(t, n); + var r = Object.prototype.toString.call(t).slice(8, -1); + return ( + "Object" === r && t.constructor && (r = t.constructor.name), + "Map" === r || "Set" === r + ? Array.from(t) + : "Arguments" === r || + /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r) + ? e(t, n) + : void 0 + ); + } + })(o) || + (function () { + throw new TypeError( + "Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method." + ); + })() + ), + c !== u - 1 && l.push(i[c]); + var p = l.length; + p > 30 && + (t = + l.slice(0, 10).join("") + + l.slice(Math.floor(p / 2) - 5, Math.floor(p / 2) + 5).join("") + + l.slice(-10).join("")); + } + for ( + var d = "" + .concat(String.fromCharCode(103)) + .concat(String.fromCharCode(116)) + .concat(String.fromCharCode(107)), + h = (null !== r ? r : (r = gtk || "") || "").split("."), + f = Number(h[0]) || 0, + m = Number(h[1]) || 0, + g = [], + y = 0, + v = 0; + v < t.length; + v++ + ) { + var _ = t.charCodeAt(v); + _ < 128 + ? (g[y++] = _) + : (_ < 2048 + ? (g[y++] = (_ >> 6) | 192) + : (55296 == (64512 & _) && + v + 1 < t.length && + 56320 == (64512 & t.charCodeAt(v + 1)) + ? ((_ = 65536 + ((1023 & _) << 10) + (1023 & t.charCodeAt(++v))), + (g[y++] = (_ >> 18) | 240), + (g[y++] = ((_ >> 12) & 63) | 128)) + : (g[y++] = (_ >> 12) | 224), + (g[y++] = ((_ >> 6) & 63) | 128)), + (g[y++] = (63 & _) | 128)); + } + for ( + var b = f, + w = + "" + .concat(String.fromCharCode(43)) + .concat(String.fromCharCode(45)) + .concat(String.fromCharCode(97)) + + "" + .concat(String.fromCharCode(94)) + .concat(String.fromCharCode(43)) + .concat(String.fromCharCode(54)), + k = + "" + .concat(String.fromCharCode(43)) + .concat(String.fromCharCode(45)) + .concat(String.fromCharCode(51)) + + "" + .concat(String.fromCharCode(94)) + .concat(String.fromCharCode(43)) + .concat(String.fromCharCode(98)) + + "" + .concat(String.fromCharCode(43)) + .concat(String.fromCharCode(45)) + .concat(String.fromCharCode(102)), + x = 0; + x < g.length; + x++ + ) + b = n((b += g[x]), w); + return ( + (b = n(b, k)), + (b ^= m) < 0 && (b = 2147483648 + (2147483647 & b)), + "".concat((b %= 1e6).toString(), ".").concat(b ^ f) + ); +} + +const getCookie = async () => { + const res = await fetch(URL_BAIDU_WEB, { + headers: { + "Content-type": "text/html; charset=utf-8", + }, + }); + + if (!res.ok) { + throw new Error(res.statusText); + } + + return res.headers.get("set-cookie"); +}; + +const getToken = async () => { + const cookie = await getCookie(); + const res = await fetch(URL_BAIDU_WEB, { + headers: { + "Content-type": "text/html; charset=utf-8", + cookie, + }, + }); + + if (!res.ok) { + throw new Error(res.statusText); + } + + const text = await res.text(); + const token = text.match(/token: '(.*)',/)[1]; + const gtk = text.match(/gtk = "(.*)";/)[1]; + const exp = Date.now() + 8 * 60 * 60 * 1000; + + return { cookie, token, gtk, exp }; +}; + +/** + * 闭包缓存token,减少对storage查询 + * @returns + */ +const _bdAuth = () => { + let store; + + return async () => { + const now = Date.now(); + + // 查询内存缓存 + if (store && store.exp > now) { + return store; + } + + // 查询storage缓存 + store = await getBdauth(); + if (store && store.exp > now) { + return store; + } + + // 缓存没有或失效,查询接口 + store = await getToken(); + await setBdauth(store); + return store; + }; +}; + +const bdAuth = _bdAuth(); + +/** + * 腾讯翻译 + * @param {*} text + * @param {*} to + * @param {*} from + * @returns + */ +export const apiBaiduTranslate = async ( + translator, + text, + to, + from, + { useCache = true } +) => { + const { cookie, token, gtk } = await bdAuth(); + const sign = getSign(text, gtk); + const data = { + from, + to, + query: text, + simple_means_flag: 3, + sign, + token, + domain: "common", + ts: Date.now(), + }; + + const res = await fetchPolyfill(`${URL_BAIDU_TRAN}?from=${from}&to=${to}`, { + headers: { + "content-type": "application/x-www-form-urlencoded; charset=UTF-8", + cookie, + }, + method: "POST", + body: queryString.stringify(data), + useCache, + usePool: true, + translator, + }); + const trText = res.trans_result?.data.map((item) => item.dst).join(" "); + const isSame = res.trans_result?.to === res.trans_result?.from; + + return [trText, isSame, res]; +}; diff --git a/src/apis/deepl.js b/src/apis/deepl.js new file mode 100644 index 0000000..cd03bce --- /dev/null +++ b/src/apis/deepl.js @@ -0,0 +1,77 @@ +import { fetchPolyfill } from "../libs/fetch"; +import { URL_DEEPLFREE_TRAN } from "../config"; + +let id = 1e4 * Math.round(1e4 * Math.random()); + +/** + * DeepL翻译 + * @param {*} text + * @param {*} to + * @param {*} from + * @returns + */ +export const apiDeepLFreeTranslate = async ( + translator, + text, + to, + from, + { useCache = true } +) => { + const iCount = (text.match(/[i]/g) || []).length + 1; + let timestamp = Date.now(); + timestamp = timestamp + (iCount - (timestamp % iCount)); + id++; + + let body = JSON.stringify({ + jsonrpc: "2.0", + method: "LMT_handle_texts", + params: { + splitting: "newlines", + lang: { + target_lang: to, + source_lang_user_selected: from, + }, + commonJobParams: { + wasSpoken: false, + transcribe_as: "", + }, + id, + timestamp, + texts: [ + { + text, + requestAlternatives: 3, + }, + ], + }, + }); + + body = body.replace( + 'method":"', + (id + 3) % 13 === 0 || (id + 5) % 29 === 0 ? 'method" : "' : 'method": "' + ); + + const res = await fetchPolyfill(URL_DEEPLFREE_TRAN, { + headers: { + "Content-Type": "application/json", + Accept: "*/*", + "x-app-os-name": "iOS", + "x-app-os-version": "16.3.0", + "Accept-Language": "en-US,en;q=0.9", + "Accept-Encoding": "gzip, deflate, br", + "x-app-device": "iPhone13,2", + "User-Agent": "DeepL-iOS/2.9.1 iOS 16.3.0 (iPhone13,2)", + "x-app-build": "510265", + "x-app-version": "2.9.1", + }, + method: "POST", + body, + useCache, + usePool: true, + translator, + }); + const trText = res.result?.texts.map((item) => item.text).join(" "); + const isSame = to === res.result?.lang; + + return [trText, isSame]; +}; diff --git a/src/apis/index.js b/src/apis/index.js index 5927298..fb0df36 100644 --- a/src/apis/index.js +++ b/src/apis/index.js @@ -4,18 +4,26 @@ import { OPT_TRANS_GOOGLE, OPT_TRANS_MICROSOFT, OPT_TRANS_DEEPL, + OPT_TRANS_DEEPLFREE, OPT_TRANS_DEEPLX, + OPT_TRANS_BAIDU, + OPT_TRANS_TENCENT, OPT_TRANS_OPENAI, OPT_TRANS_CUSTOMIZE, + URL_CACHE_TRAN, OPT_LANGS_SPECIAL, PROMPT_PLACE_FROM, PROMPT_PLACE_TO, KV_SALT_SYNC, URL_BAIDU_LANGDETECT, + URL_MICROSOFT_TRAN, OPT_LANGS_BAIDU, } from "../config"; import { tryDetectLang } from "../libs"; import { sha256 } from "../libs/utils"; +import { apiDeepLFreeTranslate } from "./deepl"; +import { apiBaiduTranslate } from "./baidu"; +import { apiTencentTranslate } from "./tencent"; /** * 同步数据 @@ -92,14 +100,14 @@ const apiMicrosoftTranslate = async ( text, to, from, - { url, useCache = true } + { useCache = true } ) => { const params = { from, to, "api-version": "3.0", }; - const input = `${url}?${queryString.stringify(params)}`; + const input = `${URL_MICROSOFT_TRAN}?${queryString.stringify(params)}`; const res = await fetchPolyfill(input, { headers: { "Content-type": "application/json", @@ -308,36 +316,61 @@ export const apiBaiduLangdetect = async (text) => { * @param {*} param0 * @returns */ -export const apiTranslate = ({ +export const apiTranslate = async ({ translator, text, fromLang, toLang, - apiSetting, + apiSetting = {}, + useCache = true, + usePool = true, }) => { - const from = OPT_LANGS_SPECIAL[translator].get(fromLang); - const to = OPT_LANGS_SPECIAL[translator].get(toLang); + let trText = ""; + let isSame = false; - if (!to) { - return ["", from === to]; - } + const transOpts = { + translator, + text, + fromLang, + toLang, + }; - const callApi = (api) => api(translator, text, to, from, apiSetting); + const res = await fetchPolyfill( + `${URL_CACHE_TRAN}?${queryString.stringify(transOpts)}`, + { + useCache, + usePool, + transOpts, + apiSetting, + } + ); switch (translator) { case OPT_TRANS_GOOGLE: - return callApi(apiGoogleTranslate); + break; case OPT_TRANS_MICROSOFT: - return callApi(apiMicrosoftTranslate); + trText = res[0].translations[0].text; + isSame = toLang === res[0].detectedLanguage?.language; + break; case OPT_TRANS_DEEPL: - return callApi(apiDeepLTranslate); + break; + case OPT_TRANS_DEEPLFREE: + break; case OPT_TRANS_DEEPLX: - return callApi(apiDeepLXTranslate); + break; + case OPT_TRANS_BAIDU: + break; + case OPT_TRANS_TENCENT: + trText = res.auto_translation; + isSame = text === trText; + break; case OPT_TRANS_OPENAI: - return callApi(apiOpenaiTranslate); + break; case OPT_TRANS_CUSTOMIZE: - return callApi(apiCustomTranslate); + break; default: - return ["", false]; + break; } + + return [trText, isSame]; }; diff --git a/src/apis/tencent.js b/src/apis/tencent.js new file mode 100644 index 0000000..69b1108 --- /dev/null +++ b/src/apis/tencent.js @@ -0,0 +1,73 @@ +import { URL_TENCENT_TRANSMART, OPT_LANGS_TENCENT } from "../config"; +import { fetchPolyfill } from "../libs/fetch"; + +/** + * 腾讯语言识别 + * @param {*} text + * @returns + */ +export const apiTencentLangdetect = async (text) => { + const body = JSON.stringify({ + header: { + fn: "text_analysis", + }, + text, + }); + + const res = await fetchPolyfill(URL_TENCENT_TRANSMART, { + headers: { + "Content-type": "application/json", + }, + method: "POST", + body, + useCache: true, + }); + + return OPT_LANGS_TENCENT.get(res.language) ?? res.language; +}; + +/** + * 腾讯翻译 + * @param {*} text + * @param {*} to + * @param {*} from + * @returns + */ +export const apiTencentTranslate = async ( + translator, + text, + to, + from, + { useCache = true } +) => { + const data = { + header: { + fn: "auto_translation_block", + }, + source: { + text_block: text, + }, + target: { + lang: to, + }, + }; + + if (from) { + data.source.lang = from; + } + + const res = await fetchPolyfill(URL_TENCENT_TRANSMART, { + headers: { + "Content-Type": "application/json", + }, + method: "POST", + body: JSON.stringify(data), + useCache, + usePool: true, + translator, + }); + const trText = res.auto_translation; + const isSame = text === trText; + + return [trText, isSame]; +}; diff --git a/src/config/index.js b/src/config/index.js index c9b1cc4..b275da5 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -20,6 +20,7 @@ export { }; export const STOKEY_MSAUTH = `${APP_NAME}_msauth`; +export const STOKEY_BDAUTH = `${APP_NAME}_bdauth`; export const STOKEY_SETTING = `${APP_NAME}_setting`; export const STOKEY_RULES = `${APP_NAME}_rules`; export const STOKEY_SYNC = `${APP_NAME}_sync`; @@ -67,21 +68,34 @@ export const URL_KISS_RULES_NEW_ISSUE = "https://github.com/fishjar/kiss-rules/issues/new"; export const URL_RAW_PREFIX = "https://raw.githubusercontent.com/fishjar/kiss-translator/master"; + +export const URL_CACHE_TRAN = `https://${APP_LCNAME}/translate`; +export const URL_MICROSOFT_TRAN = + "https://api-edge.cognitive.microsofttranslator.com/translate"; export const URL_MICROSOFT_AUTH = "https://edge.microsoft.com/translate/auth"; export const URL_BAIDU_LANGDETECT = "https://fanyi.baidu.com/langdetect"; +export const URL_BAIDU_WEB = "https://fanyi.baidu.com/"; +export const URL_BAIDU_TRAN = "https://fanyi.baidu.com/v2transapi"; +export const URL_DEEPLFREE_TRAN = "https://www2.deepl.com/jsonrpc"; +export const URL_TENCENT_TRANSMART = "https://transmart.qq.com/api/imt"; export const OPT_TRANS_GOOGLE = "Google"; export const OPT_TRANS_MICROSOFT = "Microsoft"; export const OPT_TRANS_DEEPL = "DeepL"; export const OPT_TRANS_DEEPLX = "DeepLX"; +export const OPT_TRANS_DEEPLFREE = "DeepLFree"; export const OPT_TRANS_BAIDU = "Baidu"; +export const OPT_TRANS_TENCENT = "Tencent"; export const OPT_TRANS_OPENAI = "OpenAI"; export const OPT_TRANS_CUSTOMIZE = "Custom"; export const OPT_TRANS_ALL = [ OPT_TRANS_GOOGLE, OPT_TRANS_MICROSOFT, OPT_TRANS_DEEPL, + OPT_TRANS_DEEPLFREE, OPT_TRANS_DEEPLX, + OPT_TRANS_BAIDU, + OPT_TRANS_TENCENT, OPT_TRANS_OPENAI, OPT_TRANS_CUSTOMIZE, ]; @@ -140,6 +154,12 @@ export const OPT_LANGS_SPECIAL = { ["zh-CN", "ZH"], ["zh-TW", "ZH"], ]), + [OPT_TRANS_DEEPLFREE]: new Map([ + ...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]), + ["auto", "auto"], + ["zh-CN", "ZH"], + ["zh-TW", "ZH"], + ]), [OPT_TRANS_DEEPLX]: new Map([ ...OPT_LANGS_FROM.map(([key]) => [key, key.toUpperCase()]), ["auto", ""], @@ -173,6 +193,28 @@ export const OPT_LANGS_SPECIAL = { ["uk", "ukr"], ["vi", "vie"], ]), + [OPT_TRANS_TENCENT]: new Map([ + ["auto", "auto"], + ["zh-CN", "zh"], + ["zh-TW", "zh"], + ["en", "en"], + ["ar", "ar"], + ["de", "de"], + ["ru", "ru"], + ["fr", "fr"], + ["fi", "fil"], + ["ko", "ko"], + ["ms", "ms"], + ["pt", "pt"], + ["ja", "ja"], + ["th", "th"], + ["tr", "tr"], + ["es", "es"], + ["it", "it"], + ["hi", "hi"], + ["id", "id"], + ["vi", "vi"], + ]), [OPT_TRANS_OPENAI]: new Map( OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) ), @@ -188,6 +230,13 @@ export const OPT_LANGS_BAIDU = new Map( k, ]) ); +export const OPT_LANGS_TENCENT = new Map( + Array.from(OPT_LANGS_SPECIAL[OPT_TRANS_TENCENT].entries()).map(([k, v]) => [ + v, + k, + ]) +); +OPT_LANGS_TENCENT.set("zh", "zh-CN"); export const OPT_STYLE_NONE = "style_none"; // 无 export const OPT_STYLE_LINE = "under_line"; // 下划线 @@ -285,10 +334,6 @@ export const DEFAULT_TRANS_APIS = { url: "https://translate.googleapis.com/translate_a/single", key: "", }, - [OPT_TRANS_MICROSOFT]: { - url: "https://api-edge.cognitive.microsofttranslator.com/translate", - authUrl: "https://edge.microsoft.com/translate/auth", - }, [OPT_TRANS_DEEPL]: { url: "https://api-free.deepl.com/v2/translate", key: "", diff --git a/src/hooks/Translate.js b/src/hooks/Translate.js index 74223fc..14052d5 100644 --- a/src/hooks/Translate.js +++ b/src/hooks/Translate.js @@ -32,7 +32,8 @@ export function useTranslate(q, rule, setting) { text: q, fromLang, toLang, - apiSetting: (setting.transApis || DEFAULT_TRANS_APIS)[translator], + apiSetting: + setting.transApis?.[translator] || DEFAULT_TRANS_APIS[translator], }); setText(trText); setSamelang(isSame); diff --git a/src/libs/fetch.js b/src/libs/fetch.js index ff3b21e..7a5770a 100644 --- a/src/libs/fetch.js +++ b/src/libs/fetch.js @@ -1,3 +1,4 @@ +import queryString from "query-string"; import { isExt, isGm } from "./client"; import { sendBgMsg } from "./msg"; import { taskPool } from "./pool"; @@ -6,11 +7,20 @@ import { MSG_FETCH_LIMIT, MSG_FETCH_CLEAR, CACHE_NAME, + OPT_TRANS_GOOGLE, OPT_TRANS_MICROSOFT, OPT_TRANS_DEEPL, + OPT_TRANS_DEEPLFREE, + OPT_TRANS_DEEPLX, + OPT_TRANS_BAIDU, + OPT_TRANS_TENCENT, OPT_TRANS_OPENAI, + OPT_TRANS_CUSTOMIZE, DEFAULT_FETCH_INTERVAL, DEFAULT_FETCH_LIMIT, + OPT_LANGS_SPECIAL, + URL_MICROSOFT_TRAN, + URL_TENCENT_TRANSMART, } from "../config"; import { msAuth } from "./auth"; import { isBg } from "./browser"; @@ -53,7 +63,8 @@ export const fetchGM = async (input, { method = "GET", headers, body } = {}) => * @param {*} request * @returns */ -const newCacheReq = async (request) => { +const newCacheReq = async (input, init) => { + let request = new Request(input, init); if (request.method !== "GET") { const body = await request.text(); const cacheUrl = new URL(request.url); @@ -64,22 +75,116 @@ const newCacheReq = async (request) => { return request; }; +const newTransReq = ( + { translator, text, fromLang, toLang }, + { url, key } = {} +) => { + // console.log({ translator, text, fromLang, toLang }, { url, key }); + let params; + let data; + let input; + let init; + + const from = OPT_LANGS_SPECIAL[translator].get(fromLang) ?? ""; + const to = OPT_LANGS_SPECIAL[translator].get(toLang); + if (!to) { + throw new Error(`[trans] target lang: ${toLang} not support`); + } + + switch (translator) { + case OPT_TRANS_GOOGLE: + break; + case OPT_TRANS_MICROSOFT: + params = { + from, + to, + "api-version": "3.0", + }; + input = `${URL_MICROSOFT_TRAN}?${queryString.stringify(params)}`; + init = { + headers: { + "Content-type": "application/json", + Authorization: `Bearer ${key}`, + }, + method: "POST", + body: JSON.stringify([{ Text: text }]), + }; + break; + case OPT_TRANS_DEEPL: + break; + case OPT_TRANS_DEEPLFREE: + break; + case OPT_TRANS_DEEPLX: + break; + case OPT_TRANS_BAIDU: + break; + case OPT_TRANS_TENCENT: + data = { + header: { + fn: "auto_translation_block", + }, + source: { + text_block: text, + }, + target: { + lang: to, + }, + }; + if (from) { + data.source.lang = from; + } + input = URL_TENCENT_TRANSMART; + init = { + headers: { + "Content-Type": "application/json", + }, + method: "POST", + body: JSON.stringify(data), + }; + break; + case OPT_TRANS_OPENAI: + break; + case OPT_TRANS_CUSTOMIZE: + break; + default: + break; + } + + if (!input) { + throw new Error(`[trans] translator: ${translator} not support`); + } + + return [input, init]; +}; + /** * 发起请求 * @param {*} param0 * @returns */ -export const fetchApi = async ({ input, init = {}, translator, token }) => { +export const fetchApi = async ({ + input, + init, + transOpts, + apiSetting, + token, +}) => { if (token) { - if (translator === OPT_TRANS_DEEPL) { - init.headers["Authorization"] = `DeepL-Auth-Key ${token}`; // DeepL - } else if (translator === OPT_TRANS_OPENAI) { - init.headers["Authorization"] = `Bearer ${token}`; // OpenAI - init.headers["api-key"] = token; // Azure OpenAI - } else { - init.headers["Authorization"] = `Bearer ${token}`; // Microsoft & others - } + apiSetting.key = token; } + if (transOpts?.translator) { + [input, init] = newTransReq(transOpts, apiSetting); + } + // if (token) { + // if (translator === OPT_TRANS_DEEPL) { + // init.headers["Authorization"] = `DeepL-Auth-Key ${token}`; // DeepL + // } else if (translator === OPT_TRANS_OPENAI) { + // init.headers["Authorization"] = `Bearer ${token}`; // OpenAI + // init.headers["api-key"] = token; // Azure OpenAI + // } else { + // init.headers["Authorization"] = `Bearer ${token}`; // Microsoft & others + // } + // } if (isGm) { let info; @@ -109,8 +214,8 @@ export const fetchApi = async ({ input, init = {}, translator, token }) => { */ export const fetchPool = taskPool( fetchApi, - async ({ translator }) => { - if (translator === OPT_TRANS_MICROSOFT) { + async ({ transOpts }) => { + if (transOpts?.translator === OPT_TRANS_MICROSOFT) { const [token] = await msAuth(); return { token }; } @@ -128,9 +233,9 @@ export const fetchPool = taskPool( */ export const fetchData = async ( input, - { useCache, usePool, translator, token, ...init } = {} + { useCache, usePool, transOpts, apiSetting, ...init } = {} ) => { - const cacheReq = await newCacheReq(new Request(input, init)); + const cacheReq = await newCacheReq(input, init); let res; // 查询缓存 @@ -146,9 +251,9 @@ export const fetchData = async ( if (!res) { // 发送请求 if (usePool) { - res = await fetchPool.push({ input, init, translator, token }); + res = await fetchPool.push({ input, init, transOpts, apiSetting }); } else { - res = await fetchApi({ input, init, translator, token }); + res = await fetchApi({ input, init, transOpts, apiSetting }); } if (!res?.ok) { @@ -180,7 +285,7 @@ export const fetchData = async ( * @returns */ export const fetchPolyfill = async (input, opts) => { - if (!input.trim()) { + if (!input?.trim()) { throw new Error("URL is empty"); } diff --git a/src/libs/storage.js b/src/libs/storage.js index 9c607e7..e1e9c9f 100644 --- a/src/libs/storage.js +++ b/src/libs/storage.js @@ -4,6 +4,7 @@ import { STOKEY_FAB, STOKEY_SYNC, STOKEY_MSAUTH, + STOKEY_BDAUTH, STOKEY_RULESCACHE_PREFIX, STOKEY_WEBFIXCACHE_PREFIX, DEFAULT_SETTING, @@ -134,6 +135,12 @@ export const updateSync = (obj) => putObj(STOKEY_SYNC, obj); export const getMsauth = () => getObj(STOKEY_MSAUTH); export const setMsauth = (val) => setObj(STOKEY_MSAUTH, val); +/** + * baidu auth + */ +export const getBdauth = () => getObj(STOKEY_BDAUTH); +export const setBdauth = (val) => setObj(STOKEY_BDAUTH, val); + /** * 存入默认数据 */ diff --git a/src/libs/translator.js b/src/libs/translator.js index e4edafb..32f7af6 100644 --- a/src/libs/translator.js +++ b/src/libs/translator.js @@ -360,9 +360,8 @@ export class Translator { triggerTime, transSign, } = this._inputRule; - const apiSetting = (this._setting.transApis || DEFAULT_TRANS_APIS)[ - translator - ]; + const apiSetting = + this._setting.transApis?.[translator] || DEFAULT_TRANS_APIS[translator]; const { detectRemote } = this._setting; let triggerShortcut = initTriggerShortcut; diff --git a/src/views/Options/Apis.js b/src/views/Options/Apis.js index 829a97d..df4c76b 100644 --- a/src/views/Options/Apis.js +++ b/src/views/Options/Apis.js @@ -5,6 +5,9 @@ import CircularProgress from "@mui/material/CircularProgress"; import { OPT_TRANS_ALL, OPT_TRANS_MICROSOFT, + OPT_TRANS_DEEPLFREE, + OPT_TRANS_BAIDU, + OPT_TRANS_TENCENT, OPT_TRANS_OPENAI, OPT_TRANS_CUSTOMIZE, URL_KISS_PROXY, @@ -71,9 +74,16 @@ function ApiFields({ translator }) { }); }; + const buildinTranslators = [ + OPT_TRANS_MICROSOFT, + OPT_TRANS_DEEPLFREE, + OPT_TRANS_BAIDU, + OPT_TRANS_TENCENT, + ]; + return ( - {translator !== OPT_TRANS_MICROSOFT && ( + {!buildinTranslators.includes(translator) && ( <> - {translator !== OPT_TRANS_MICROSOFT && ( + {!buildinTranslators.includes(translator) && (