Files
ComfyUI-OpenClaw/web/admin_console_api.js
T

130 lines
4.0 KiB
JavaScript

import {
API_PREFIXES,
STORAGE_KEYS,
buildRemoteAdminHeaders,
getMirroredStorageValue,
setMirroredStorageValue,
} from "./openclaw_compat.js";
function parseResponseText(text) {
try {
return text ? JSON.parse(text) : null;
} catch {
return { raw: text };
}
}
export function parseSseChunk(chunk) {
const lines = String(chunk || "").split(/\r?\n/);
let type = "message";
const dataLines = [];
lines.forEach((line) => {
if (line.startsWith("event:")) {
type = line.slice(6).trim() || "message";
} else if (line.startsWith("data:")) {
dataLines.push(line.slice(5).trim());
}
});
if (!dataLines.length) return null;
const raw = dataLines.join("\n");
const payload = parseResponseText(raw) || { raw };
payload.event_type = payload.event_type || type;
return payload;
}
export function createRemoteAdminApi({
fetchImpl = fetch.bind(globalThis),
storage = globalThis.localStorage,
tokenSpec = STORAGE_KEYS.local.remoteAdminToken,
prefixes = API_PREFIXES,
headerBuilder = buildRemoteAdminHeaders,
} = {}) {
const state = {
canonicalPrefix: prefixes.canonical,
legacyPrefix: prefixes.legacy,
token: getMirroredStorageValue(storage, tokenSpec) || "",
lastSeq: 0,
sseAbort: null,
};
const getHeaders = () => headerBuilder(state.token || "");
async function request(path, options = {}) {
const urls = [`${state.canonicalPrefix}${path}`, `${state.legacyPrefix}${path}`];
let last = { ok: false, status: 0, error: "request_failed" };
for (const url of urls) {
try {
const response = await fetchImpl(url, {
method: options.method || "GET",
headers: {
...getHeaders(),
...(options.body ? { "Content-Type": "application/json" } : {}),
...(options.headers || {}),
},
body: options.body ? JSON.stringify(options.body) : undefined,
signal: options.signal,
});
const text = await response.text();
const data = parseResponseText(text);
if (response.status === 404) {
last = { ok: false, status: 404, error: "not_found", data };
continue;
}
return {
ok: response.ok,
status: response.status,
error: (data && data.error) || (!response.ok ? response.statusText : ""),
data,
url,
};
} catch (error) {
last = { ok: false, status: 0, error: String(error) };
}
}
return last;
}
async function openStream(path, options = {}) {
const urls = [`${state.canonicalPrefix}${path}`, `${state.legacyPrefix}${path}`];
for (const url of urls) {
try {
const response = await fetchImpl(url, {
method: options.method || "GET",
headers: {
...getHeaders(),
...(options.headers || {}),
},
signal: options.signal,
});
if (response.status === 404) {
continue;
}
return response;
} catch {
// try next compatible path
}
}
return null;
}
return {
state,
request,
openStream,
getHeaders,
getToken() {
return state.token;
},
setToken(token) {
state.token = String(token || "").trim();
setMirroredStorageValue(storage, tokenSpec, state.token);
return state.token;
},
clearToken() {
state.token = "";
setMirroredStorageValue(storage, tokenSpec, "");
},
};
}