import { app } from "./app.js"; import { api } from "./api.js"; import { ComfyWidgets, LGraphNode } from "./widgets.js"; /** @typedef {import('../../../web/types/comfy.js').ComfyExtension} ComfyExtension*/ /** @type {ComfyExtension} */ const ext = { name: "BennyKok.ComfyUIDeploy", init(app) { addButton(); }, registerCustomNodes() { /** @type {LGraphNode}*/ class ComfyDeploy { color = LGraphCanvas.node_colors.yellow.color; bgcolor = LGraphCanvas.node_colors.yellow.bgcolor; groupcolor = LGraphCanvas.node_colors.yellow.groupcolor; constructor() { if (!this.properties) { this.properties = {}; this.properties.workflow_name = ""; this.properties.workflow_id = ""; this.properties.version = ""; } ComfyWidgets.STRING( this, "workflow_name", ["", { default: this.properties.workflow_name, multiline: false }], app, ); ComfyWidgets.STRING( this, "workflow_id", ["", { default: this.properties.workflow_id, multiline: false }], app, ); ComfyWidgets.STRING( this, "version", ["", { default: this.properties.version, multiline: false }], app, ); // this.widgets.forEach((w) => { // // w.computeSize = () => [200,10] // w.computedHeight = 2; // }) this.widgets_start_y = 10; this.setSize(this.computeSize()); // const config = { }; // console.log(this); this.serialize_widgets = true; this.isVirtualNode = true; } } // Load default visibility LiteGraph.registerNodeType( "ComfyDeploy", Object.assign(ComfyDeploy, { title_mode: LiteGraph.NORMAL_TITLE, title: "Comfy Deploy", collapsable: true, }), ); ComfyDeploy.category = "deploy"; }, async setup() { // const graphCanvas = document.getElementById("graph-canvas"); window.addEventListener("message", (event) => { if (!event.data.flow || Object.entries(event.data.flow).length <= 0) return; // updateBlendshapesPrompts(event.data.flow); }); api.addEventListener("executed", (evt) => { const images = evt.detail?.output.images; // if (images?.length > 0 && images[0].type === "output") { // generatedImages[evt.detail.node] = images[0].filename; // } // if (evt.detail?.output.gltfFilename) { // } }); }, }; /** * @typedef {import('../../../web/types/litegraph.js').LGraph} LGraph * @typedef {import('../../../web/types/litegraph.js').LGraphNode} LGraphNode */ function addButton() { const menu = document.querySelector(".comfy-menu"); const deploy = document.createElement("button"); deploy.style.position = "relative"; deploy.style.display = "block"; deploy.innerHTML = "
"; deploy.onclick = async () => { /** @type {LGraph} */ const graph = app.graph; const title = deploy.querySelector("#button-title") const deployMeta = graph.findNodesByType("ComfyDeploy"); const deployMetaNode = deployMeta[0]; console.log(deployMetaNode); const workflow_name = deployMetaNode.widgets[0].value; const workflow_id = deployMetaNode.widgets[1].value; console.log(workflow_name, workflow_id); const prompt = await app.graphToPrompt(); console.log(graph); console.log(prompt); // const endpoint = localStorage.getItem("endpoint") ?? ""; // const apiKey = localStorage.getItem("apiKey"); const { endpoint, apiKey, } = getData(); if (!endpoint || !apiKey || apiKey === "" || endpoint === "") { configDialog.show(); return; } title.innerText = "Deploying..."; title.style.color = "orange"; console.log(prompt); // TODO trim the ending / from endpoint is there is if (endpoint.endsWith("/")) { endpoint = endpoint.slice(0, -1); } const apiRoute = endpoint + "/api/upload" // const userId = apiKey try { let data = await fetch(apiRoute, { method: "POST", body: JSON.stringify({ workflow_name, workflow_id, workflow: prompt.workflow, workflow_api: prompt.output, }), headers: { "Content-Type": "application/json", "Authorization": "Bearer " + apiKey, }, }); console.log(data); if (data.status !== 200) { throw new Error(await data.text()); } else { data = await data.json(); } title.textContent = "Done"; title.style.color = "green"; deployMetaNode.widgets[1].value = data.workflow_id; deployMetaNode.widgets[2].value = data.version; graph.change(); infoDialog.show( `Deployed successfully!