diff --git a/src/apis/index.js b/src/apis/index.js index def89f0..d6c5828 100644 --- a/src/apis/index.js +++ b/src/apis/index.js @@ -264,6 +264,25 @@ export const apiTranslate = async ({ case OPT_TRANS_CUSTOMIZE_5: trText = res.text; isSame = to === res.from; + + const { customOption } = apiSetting; + if (customOption.trim()) { + try { + const opt = JSON.parse(customOption); + const textPattern = opt.resPattern?.text; + const fromPattern = opt.resPattern?.from; + if (textPattern) { + trText = textPattern.split(".").reduce((pre, cur) => pre[cur], res); + } + if (fromPattern) { + isSame = + to === fromPattern.split(".").reduce((pre, cur) => pre[cur], res); + } + } catch (err) { + throw new Error(`custom option parse err: ${err}`); + } + } + break; default: } diff --git a/src/config/i18n.js b/src/config/i18n.js index 66119d0..14a9fb2 100644 --- a/src/config/i18n.js +++ b/src/config/i18n.js @@ -42,24 +42,28 @@ const customApiLangs = `["en", "English - English"], ["vi", "Vietnamese - Tiếng Việt"], `; -const customApiHelpZH = `/// 自定义翻译源接口说明 - -// 请求(Request)数据将按下面规范发送 -{ - url: {{YOUR_URL}}, - method: "POST", - headers: { +const customDefaultOption = `{ + "url": "{{url}}", + "method": "POST", + "headers": { "Content-type": "application/json", - "Authorization": "Bearer {{YOUR_KEY}}", + "Authorization": "Bearer {{key}}" }, - body: { - text: "", // 需要翻译的文字 - from: "", // 源语言,可能为空,表示需要接口自动识别语言 - to: "", // 目标语言 + "body": { + "text": "{{text}}", + "from": "{{from}}", + "to": "{{to}}" + }, + "resPattern": { + "text": "text", + "from": "from" } -} +}`; -// 返回(Response)数据需符合下面的JSON规范 +const customApiHelpZH = `// 自定义选项范例 +${customDefaultOption} + +// 返回数据默认格式 { text: "", // 翻译后的文字 from: "", // 识别的源语言 @@ -70,24 +74,10 @@ const customApiHelpZH = `/// 自定义翻译源接口说明 ${customApiLangs} `; -const customApiHelpEN = `/// Custom translation source interface description +const customApiHelpEN = `// Example of custom options +${customDefaultOption} -// Request data will be sent according to the following specifications -{ - url: {{YOUR_URL}}, - method: "POST", - headers: { - "Content-type": "application/json", - "Authorization": "Bearer {{YOUR_KEY}}", - }, - body: { - text: "", // text to be translated - from: "", // Source language, may be empty - to: "", // Target language - } -} - -// The returned data must conform to the following JSON specification +// Return data default format { text: "", // translated text from: "", // Recognized source language @@ -851,4 +841,8 @@ export const I18N = { zh: `附加样式`, en: `Extend Styles`, }, + custom_option: { + zh: `自定义选项`, + en: `Custom Option`, + }, }; diff --git a/src/config/index.js b/src/config/index.js index 3a0da28..fc4a312 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -458,7 +458,7 @@ export const DEFAULT_SUBRULES_LIST = [ const defaultCustomApi = { url: "", key: "", - customRequest: "", + customOption: "", fetchLimit: DEFAULT_FETCH_LIMIT, fetchInterval: DEFAULT_FETCH_INTERVAL, }; diff --git a/src/libs/req.js b/src/libs/req.js index 3468d12..0b54a3c 100644 --- a/src/libs/req.js +++ b/src/libs/req.js @@ -27,7 +27,6 @@ import { import { msAuth } from "./auth"; import { genDeeplFree } from "../apis/deepl"; import { genBaidu } from "../apis/baidu"; -import { kissLog } from "./log"; const keyMap = new Map(); @@ -279,7 +278,7 @@ const genCloudflareAI = ({ text, from, to, url, key }) => { return [url, init]; }; -const genCustom = ({ text, from, to, url, key, customRequest = "" }) => { +const genCustom = ({ text, from, to, url, key, customOption = "" }) => { const replaceInput = (str) => str .replaceAll(INPUT_PLACE_URL, url) @@ -304,19 +303,19 @@ const genCustom = ({ text, from, to, url, key, customRequest = "" }) => { } url = replaceInput(url); - if (customRequest.trim()) { + if (customOption.trim()) { try { - const req = JSON.parse(replaceInput(customRequest)); - req.url && (url = req.url); - req.headers && (init.headers = req.headers); - req.method && (init.method = req.method); + const opt = JSON.parse(replaceInput(customOption)); + opt.url && (url = opt.url); + opt.headers && (init.headers = opt.headers); + opt.method && (init.method = opt.method); if (init.method === "GET") { delete init.body; } else { - req.body && (init.body = JSON.stringify(req.body)); + opt.body && (init.body = JSON.stringify(opt.body)); } } catch (err) { - kissLog(err, "parse custom request"); + throw new Error(`custom option parse err: ${err}`); } } diff --git a/src/views/Options/Apis.js b/src/views/Options/Apis.js index d0786f4..c51fdc6 100644 --- a/src/views/Options/Apis.js +++ b/src/views/Options/Apis.js @@ -113,7 +113,7 @@ function ApiFields({ translator }) { fetchInterval = DEFAULT_FETCH_INTERVAL, dictNo = "", memoryNo = "", - customRequest = "", + customOption = "", } = api; const handleChange = (e) => { @@ -226,9 +226,9 @@ function ApiFields({ translator }) { {translator.startsWith(OPT_TRANS_CUSTOMIZE) && (