Files
sprite-ai/server/comfy.ts
T
2026-09-23 21:56:40 +03:00

55 lines
2.2 KiB
TypeScript

// Клиент ComfyUI API.
import { COMFY } from './config.ts';
export class ComfyError extends Error {}
export async function comfyJson<T = unknown>(pathname: string, body?: unknown): Promise<T> {
let r: Response;
try {
r = await fetch(new URL(pathname, COMFY), body === undefined ? undefined : {
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body),
});
} catch {
throw new ComfyError('ComfyUI недоступен по адресу ' + COMFY.origin);
}
const text = await r.text();
let json: { error?: { message?: string } | string } | undefined;
try { json = JSON.parse(text); } catch { /* не JSON */ }
if (!r.ok) {
const e = json?.error;
throw new ComfyError(typeof e === 'string' ? e : e?.message ?? JSON.stringify(json ?? text));
}
return json as T;
}
/** Ставит граф в очередь, возвращает prompt_id. */
export async function queuePrompt(graph: object): Promise<string> {
const r = await comfyJson<{ prompt_id: string }>('/prompt', { prompt: graph });
return r.prompt_id;
}
/** Загрузка картинки в ComfyUI/input/<subfolder>. При совпадении имени ComfyUI сам даёт новое имя. */
export async function uploadImage(name: string, data: Blob, subfolder: string) {
const form = new FormData();
form.append('image', data, name);
form.append('subfolder', subfolder);
let r: Response;
try {
r = await fetch(new URL('/upload/image', COMFY), { method: 'POST', body: form });
} catch {
throw new ComfyError('ComfyUI недоступен');
}
if (!r.ok) throw new ComfyError('ComfyUI не принял файл: ' + await r.text());
const j = await r.json() as { name: string; subfolder?: string; type?: string };
return { filename: j.name, subfolder: j.subfolder ?? '', type: j.type ?? 'input' };
}
/** GET /view — файл из папок ComfyUI как есть (Response для потоковой отдачи). */
export async function view(params: URLSearchParams): Promise<Response> {
try {
return await fetch(new URL('/view?' + params, COMFY));
} catch {
throw new ComfyError('ComfyUI недоступен');
}
}