// 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 };