Files
2025-11-03 19:48:59 +11:00

140 lines
4.1 KiB
JavaScript

// import fs from 'node:fs/promises';
import workflowDatas from '~/components/tabs/WorkflowsList.js';
import serverNodes from '~/server/nodes/index.js';
class ServerNodes {
constructor() {
this.path = 'server_nodes';
}
async importServerNode(type) {
return serverNodes[type];
}
processApiNode(node, id, workflowData, opts) {
return this.importServerNode(node.class_type).then((serverNode) => {
if (serverNode?.processApiNode) {
return serverNode.processApiNode(node, id, workflowData, opts);
}
});
}
processWorkflowNode(node, workflowData, opts) {
return this.importServerNode(node.type).then((serverNode) => {
if (serverNode?.processWorkflowNode) {
return serverNode.processWorkflowNode(node, workflowData, opts);
}
});
}
}
function getWorkflowData(name) {
return JSON.parse(JSON.stringify(workflowDatas[name]));
}
export default defineEventHandler(async (event) => {
const session = await getUserSession(event);
const userFolder = getUserFolder(session);
const body = await readBody(event);
const postObj = JSON.parse(body);
const client_id = postObj.client_id;
const name = fixTypeName(postObj.name);
const workflowData = getWorkflowData(name);
// const data = await fs.readFile(`components/tabs/${name}/workflow.json`, 'utf8');
// const workflowData = JSON.parse(data);
const { workflow_api, workflowIds, price } = workflowData;
if(hasDB()) {
const { queueAmount } = await updateUserPromptsDB(userFolder);
const user = await new UsersDB().getUser(userFolder);
const userAmount = user?.amount || 0;
const totalCanSpend = (userAmount - queueAmount);
if (totalCanSpend < price) {
const message = `Not enough credits. In queue: $${centsToCurrency(queueAmount)}, Account: $${centsToCurrency(userAmount)}, Cost: $${centsToCurrency(price)}`;
console.warn(userFolder, message);
throw createError({
statusCode: 500,
statusMessage: "Not enough credits",
data: { ok: false, message }
});
}
}
const serverNodes = new ServerNodes();
for (const num in postObj.workflow) {
if (!workflowIds[num]) {
if (workflow_api[num]) {
console.error('Not allowed to change this node', num);
} else {
console.error('Cannot find node', num);
}
continue;
}
const node = workflow_api[num];
if (!node) {
console.error('no node in workflow_api. id:', num, postObj.name, workflow_api);
continue;
}
const val = postObj.workflow[num];
if (!node.inputs) {
console.error('no inputs:', node);
}
for (const vname in val) {
node.inputs[vname] = val[vname];
}
await serverNodes.processApiNode(
node, num, workflowData,
{postObj, userFolder}
);
}
if (workflowData.workflow?.nodes) {
for (const node of workflowData.workflow.nodes) {
await serverNodes.processWorkflowNode(node, workflowData, postObj);
}
}
if (postObj.debug) {
console.log('workflow_api', JSON.stringify(workflow_api, null, 4));
// return null;
}
const prompt = { prompt: workflow_api, client_id };
// prompt.prompt.save_image_websocket_node = {
// "class_type": "SaveImageWebsocket",
// "inputs": {
// "images": [
// "8",
// 0
// ]
// }
// };
const resp =await fetchComfy(`${comfyUrl()}/prompt`, {
method: 'POST',
body: JSON.stringify(prompt),
});
if (resp.status !== 200) {
console.error('Prompt failed', resp, JSON.stringify(prompt, null, 4));
const statusMessage = `Prompt failed: ${resp.status} ${resp.statusText}, ${await resp.text()}`;
throw createError({
statusCode: 500,
statusMessage,
data: { ok: false, message: statusMessage }
});
}
const obj = await resp.json();
if(hasDB()) {
const prompt_id = obj.prompt_id;
// do this in background or else we won't get the prompt id for the websocket quickly enough
await (new PromptDB().addPromptToQueue(userFolder,
{
prompt_id,
price,
}));
}
return obj;
});