55 lines
2.0 KiB
JavaScript
55 lines
2.0 KiB
JavaScript
// TD工具箱自定义协议解析。保持纯 Node 实现,便于单独测试。
|
|
const { URL } = require("url");
|
|
|
|
const SCHEME = "tdtoolbox";
|
|
|
|
function trim(value) {
|
|
return String(value || "").trim();
|
|
}
|
|
|
|
function isHttpUrl(value) {
|
|
try {
|
|
const u = new URL(value);
|
|
return u.protocol === "https:" || u.protocol === "http:";
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function parseTdToolboxImport(rawUrl) {
|
|
let url;
|
|
try {
|
|
url = new URL(String(rawUrl || ""));
|
|
} catch {
|
|
return { ok: false, error: "深链格式无效" };
|
|
}
|
|
if (url.protocol !== `${SCHEME}:`) return { ok: false, error: "深链协议无效" };
|
|
if (url.host !== "v1" || url.pathname !== "/import") return { ok: false, error: "深链接口不存在" };
|
|
|
|
const q = url.searchParams;
|
|
const input = {
|
|
resource: trim(q.get("resource")),
|
|
app: trim(q.get("app")),
|
|
name: trim(q.get("name")),
|
|
endpoint: trim(q.get("endpoint")),
|
|
apiKey: trim(q.get("apiKey")),
|
|
model: trim(q.get("model")),
|
|
source: trim(q.get("source")),
|
|
sourceGroupId: trim(q.get("sourceGroupId")),
|
|
};
|
|
|
|
if (input.resource !== "provider") return { ok: false, error: "仅支持导入 provider 资源" };
|
|
if (input.app !== "codex") return { ok: false, error: "仅支持 Codex 分组导入" };
|
|
if (input.source !== "sub2api") return { ok: false, error: "仅支持 Sub2API 来源" };
|
|
if (!input.name || input.name.length > 80) return { ok: false, error: "分组名称无效" };
|
|
if (!isHttpUrl(input.endpoint)) return { ok: false, error: "API 地址必须是 http/https URL" };
|
|
if (!input.apiKey || input.apiKey.length > 4096) return { ok: false, error: "API 密钥无效" };
|
|
if (!input.model || input.model.length > 200) return { ok: false, error: "模型无效" };
|
|
if (!/^[A-Za-z0-9_-]{1,128}$/.test(input.sourceGroupId)) return { ok: false, error: "来源分组 ID 无效" };
|
|
|
|
input.name = input.name.replace(/[\r\n\0]/g, "");
|
|
return { ok: true, input };
|
|
}
|
|
|
|
module.exports = { SCHEME, parseTdToolboxImport };
|