feat: custom request

This commit is contained in:
Gabe Yuan
2024-04-17 22:35:12 +08:00
parent e369321c66
commit 9455670e80
5 changed files with 57 additions and 45 deletions

View File

@@ -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:
}

View File

@@ -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`,
},
};

View File

@@ -458,7 +458,7 @@ export const DEFAULT_SUBRULES_LIST = [
const defaultCustomApi = {
url: "",
key: "",
customRequest: "",
customOption: "",
fetchLimit: DEFAULT_FETCH_LIMIT,
fetchInterval: DEFAULT_FETCH_INTERVAL,
};

View File

@@ -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}`);
}
}

View File

@@ -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) && (
<TextField
size="small"
label={"CUSTOM REQUEST"}
name="customRequest"
value={customRequest}
label={i18n("custom_option")}
name="customOption"
value={customOption}
onChange={handleChange}
multiline
/>