- 六协议调试:HTTP/GraphQL/WebSocket/SSE/Socket.IO/MQTT
- 集合树/多标签/多环境变量/历史记录,localStorage 持久化
- 导入:OpenAPI 2/3/3.1、Postman、Apifox、Apipost、cURL、HAR、
Insomnia、Hoppscotch、Markdown(自动识别,21 个单测覆盖)
- 导出:OpenAPI 3.0 JSON/YAML、Postman v2.1、Markdown 文档、
全量备份;单请求生成 cURL/fetch/Python/Go 代码
- Gin 服务:HTTP 代理、NDJSON 流式代理(SSE 透传)、
WebSocket 隧道(浏览器自定义握手 Header)
- 内置产品官网 /home 与用户文档站 /docs(SSR,随二进制交付)
- lucide 图标体系 + 品牌标识(Logo/favicon),明暗双主题
- 环境变量:彩色徽标切换器、管理弹窗、{{ 自动补全
69 lines
2.0 KiB
TypeScript
69 lines
2.0 KiB
TypeScript
import type { HttpResult, HttpSpec, Transport, WsSession, WsSpec } from "@opsxapi/core";
|
|
|
|
async function invoke<T>(cmd: string, args?: Record<string, unknown>): Promise<T> {
|
|
try {
|
|
const { invoke: tauriInvoke } = await import("@tauri-apps/api/core");
|
|
return await tauriInvoke<T>(cmd, args);
|
|
} catch (e) {
|
|
const msg = e instanceof Error ? e.message : String(e);
|
|
throw new Error(
|
|
`tauri-native invoke("${cmd}") failed (are you running inside OpsxAPI desktop?): ${msg}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
export const tauriNativeTransport: Transport = {
|
|
async http(spec: HttpSpec): Promise<HttpResult> {
|
|
return invoke<HttpResult>("http_send", { spec });
|
|
},
|
|
|
|
ws(spec: WsSpec): WsSession {
|
|
const messageCbs: Array<(data: string) => void> = [];
|
|
const statusCbs: Array<(s: string) => void> = [];
|
|
let sessionId: string | null = null;
|
|
|
|
const emitStatus = (s: string) => statusCbs.forEach((cb) => cb(s));
|
|
|
|
void (async () => {
|
|
try {
|
|
emitStatus("connecting");
|
|
sessionId = await invoke<string>("ws_connect", { spec });
|
|
emitStatus("open");
|
|
// Full event listen pipeline is Week 2; stub keeps UI usable.
|
|
} catch (e) {
|
|
emitStatus("error");
|
|
messageCbs.forEach((cb) =>
|
|
cb(`[ws_connect error] ${e instanceof Error ? e.message : String(e)}`),
|
|
);
|
|
}
|
|
})();
|
|
|
|
return {
|
|
onMessage(cb) {
|
|
messageCbs.push(cb);
|
|
},
|
|
onStatus(cb) {
|
|
statusCbs.push(cb);
|
|
},
|
|
send(data) {
|
|
if (!sessionId) {
|
|
messageCbs.forEach((cb) => cb("[ws] not connected"));
|
|
return;
|
|
}
|
|
void invoke("ws_send", { sessionId, data }).catch((e) => {
|
|
messageCbs.forEach((cb) =>
|
|
cb(`[ws_send error] ${e instanceof Error ? e.message : String(e)}`),
|
|
);
|
|
});
|
|
},
|
|
close() {
|
|
if (!sessionId) return;
|
|
void invoke("ws_close", { sessionId }).finally(() => {
|
|
sessionId = null;
|
|
emitStatus("closed");
|
|
});
|
|
},
|
|
};
|
|
},
|
|
};
|