223 lines
6.3 KiB
JavaScript
223 lines
6.3 KiB
JavaScript
import _ from 'https://cdn.jsdelivr.net/npm/@esm-bundle/lodash@4.17.21/+esm'
|
|
import { app } from './comfy/comfy.js';
|
|
import { inputDialog } from './comfy/ui.js';
|
|
import { getData } from './store.js';
|
|
|
|
/**
|
|
* HELPERS
|
|
*
|
|
* File for helper functions, local network api's
|
|
*/
|
|
|
|
export function formatTimestamp(timestamp) {
|
|
const date = new Date(timestamp);
|
|
|
|
const year = date.getFullYear();
|
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
const day = String(date.getDate()).padStart(2, '0');
|
|
const hour = String(date.getHours()).padStart(2, '0');
|
|
const minute = String(date.getMinutes()).padStart(2, '0');
|
|
const second = String(date.getSeconds()).padStart(2, '0');
|
|
|
|
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
|
|
}
|
|
|
|
export function formatDuration(seconds) {
|
|
if (seconds < 60) {
|
|
return seconds.toFixed(2) + " seconds";
|
|
} else if (seconds < 3600) {
|
|
return (seconds / 60).toFixed(2) + " minutes";
|
|
} else {
|
|
return (seconds / 3600).toFixed(2) + " hours";
|
|
}
|
|
}
|
|
|
|
export const compareDates = (a, b) => {
|
|
return b.date - a.date; // Sort in descending order (most recent to least recent)
|
|
};
|
|
|
|
|
|
export function generateUUID() {
|
|
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
const r = Math.random() * 16 | 0;
|
|
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
return v.toString(16);
|
|
});
|
|
return uuid;
|
|
}
|
|
|
|
|
|
export const createMetaNode = async () => {
|
|
const text = await inputDialog.input(
|
|
"Create your deployment",
|
|
"Workflow name",
|
|
);
|
|
if (!text) throw new Error("Node not created");
|
|
app.graph.beforeChange();
|
|
|
|
var node = LiteGraph.createNode("ComfyCloud");
|
|
|
|
node.configure({
|
|
widgets_values: [text],
|
|
properties: {
|
|
workflow_name: text,
|
|
}
|
|
});
|
|
node.pos = [0, 0];
|
|
|
|
app.graph.add(node);
|
|
app.graph.afterChange();
|
|
}
|
|
|
|
export const getUser = async () => {
|
|
const { user } = await fetch(
|
|
'/comfy-cloud/user',
|
|
).then((x) => x.json())
|
|
|
|
return user;
|
|
}
|
|
|
|
export const getApiToken = () => {
|
|
const { apiKey } = getData();
|
|
return apiKey;
|
|
}
|
|
|
|
export const getWorkflowName = () => {
|
|
let deployMeta = app.graph.findNodesByType("ComfyCloud");
|
|
const deployMetaNode = deployMeta[0];
|
|
// @todo
|
|
// handle no deployMetaNode
|
|
|
|
if(deployMetaNode) {
|
|
const { workflow_name } = deployMetaNode.properties;
|
|
//const name = deployMetaNode.widgets[0].value;
|
|
return workflow_name;
|
|
} else {
|
|
return null
|
|
}
|
|
}
|
|
export const getWorkflowId = () => {
|
|
let deployMeta = app.graph.findNodesByType("ComfyCloud");
|
|
const deployMetaNode = deployMeta[0];
|
|
|
|
// @todo
|
|
// handle no deployMetaNode
|
|
|
|
if(deployMetaNode) {
|
|
const { workflow_id } = deployMetaNode.properties;
|
|
//const workflow_id = deployMetaNode.widgets[1].value;
|
|
return workflow_id;
|
|
} else {
|
|
return null
|
|
}
|
|
}
|
|
export const getVersion = () => {
|
|
let deployMeta = app.graph.findNodesByType("ComfyCloud");
|
|
const deployMetaNode = deployMeta[0];
|
|
// @todo
|
|
// handle no deployMetaNode
|
|
|
|
const { version } = deployMetaNode.properties;
|
|
//const version = deployMetaNode.widgets[2].value;
|
|
return version;
|
|
}
|
|
|
|
export const setWorkflowId = (id) => {
|
|
let deployMeta = app.graph.findNodesByType("ComfyCloud");
|
|
const deployMetaNode = deployMeta[0];
|
|
// @todo
|
|
// handle no deployMetaNode
|
|
//deployMetaNode.widgets[1].value = version;
|
|
deployMetaNode.properties.workflow_id = id;
|
|
}
|
|
export const setVersion = (version) => {
|
|
let deployMeta = app.graph.findNodesByType("ComfyCloud");
|
|
const deployMetaNode = deployMeta[0];
|
|
// @todo
|
|
// handle no deployMetaNode
|
|
//deployMetaNode.widgets[2].value = version;
|
|
deployMetaNode.properties.version = version;
|
|
}
|
|
|
|
export const isCustomNode = (class_type) => {
|
|
const defaultCustomNodes = ["KSampler","KSamplerAdvanced","CheckpointLoader","CheckpointLoaderSimple","VAELoader","LoraLoader","CLIPLoader","ControlNetLoader","DiffControlNetLoader","StyleModelLoader","CLIPVisionLoader","UpscaleModelLoader","CLIPVisionEncode","StyleModelApply","CLIPTextEncode","CLIPSetLastLayer","ConditioningCombine","ConditioningAverage ","ConditioningConcat","ConditioningSetArea","ConditioningSetAreaPercentage","ConditioningSetMask","ControlNetApply","ControlNetApplyAdvanced","VAEEncodeForInpaint","SetLatentNoiseMask","VAEDecode","VAEEncode","LatentRotate","LatentFlip","LatentCrop","EmptyLatentImage","LatentUpscale","LatentUpscaleBy","LatentComposite","LatentBlend","LatentFromBatch","RepeatLatentBatch","SaveImage","PreviewImage","LoadImage","LoadImageMask","ImageScale","ImageScaleBy","ImageUpscaleWithModel","ImageInvert","ImagePadForOutpaint","ImageBatch","VAEDecodeTiled","VAEEncodeTiled"]
|
|
|
|
if (defaultCustomNodes.indexOf(class_type) !== -1) {
|
|
return true
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export const getCustomNodesList = async () => {
|
|
const custom_nodes_list = await fetch("/comfy-cloud/custom-nodes-list", {
|
|
method: "get",
|
|
}).then((x) => x.json())
|
|
|
|
return custom_nodes_list.custom_nodes
|
|
}
|
|
|
|
|
|
// Exec
|
|
// returns new changes
|
|
export const compareWorkflows = (local, cloud) => {
|
|
const changes = _.differenceWith(_.toPairs(local), _.toPairs(cloud), _.isEqual)
|
|
//const changes = _.difference(_.toPairs(cloud), _.toPairs(local), _.isEqual)
|
|
|
|
const diff = changes.reduce((acc, [key, value]) => {
|
|
acc[key] = value;
|
|
return acc;
|
|
}, {});
|
|
|
|
//console.log(local, cloud, diff)
|
|
return diff
|
|
}
|
|
|
|
export async function validatePrompt(workflow_api) {
|
|
app.lastNodeErrors = null;
|
|
|
|
const body = {
|
|
workflow_api,
|
|
}
|
|
|
|
const data = await fetch("/comfy-cloud/validate-prompt", {
|
|
method: "POST",
|
|
body: JSON.stringify(body),
|
|
}).then((x) => x.json())
|
|
|
|
app.lastNodeErrors = data.node_errors;
|
|
|
|
if (data.node_errors.length > 0) {
|
|
app.canvas.draw(true, true);
|
|
}
|
|
|
|
if(data.is_valid){
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export function extractAfterInput(inputString) {
|
|
// Check if the string contains 'input'
|
|
if (inputString.includes('input')) {
|
|
// Find the index of 'input/'
|
|
const index = inputString.indexOf('input/');
|
|
|
|
// Check if 'input/' is found
|
|
if (index !== -1) {
|
|
// Return the substring after 'input/'
|
|
return inputString.substring(index + 'input/'.length);
|
|
} else {
|
|
throw new Error("Path is not in input folder")
|
|
|
|
}
|
|
}
|
|
|
|
// Return null if 'input' is not found or 'input/' is not found
|
|
return null;
|
|
}
|
|
|
|
|
|
export const isWorkflowUpToDate = diffDeps => _.isEmpty(diffDeps);
|