mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-13 09:00:16 +00:00
Format everything (#211)
This commit is contained in:
@@ -20,7 +20,10 @@ export class EzConnection {
|
||||
link;
|
||||
|
||||
get originNode() {
|
||||
return new EzNode(this.app, this.app.graph.getNodeById(this.link.origin_id));
|
||||
return new EzNode(
|
||||
this.app,
|
||||
this.app.graph.getNodeById(this.link.origin_id)
|
||||
);
|
||||
}
|
||||
|
||||
get originOutput() {
|
||||
@@ -28,7 +31,10 @@ export class EzConnection {
|
||||
}
|
||||
|
||||
get targetNode() {
|
||||
return new EzNode(this.app, this.app.graph.getNodeById(this.link.target_id));
|
||||
return new EzNode(
|
||||
this.app,
|
||||
this.app.graph.getNodeById(this.link.target_id)
|
||||
);
|
||||
}
|
||||
|
||||
get targetInput() {
|
||||
@@ -121,7 +127,11 @@ export class EzOutput extends EzSlot {
|
||||
/**
|
||||
* @type { LG["LLink"] | null }
|
||||
*/
|
||||
const link = this.node.node.connect(this.index, input.node.node, input.index);
|
||||
const link = this.node.node.connect(
|
||||
this.index,
|
||||
input.node.node,
|
||||
input.index
|
||||
);
|
||||
if (!link) {
|
||||
const inp = input.input;
|
||||
const inName = inp.name || inp.label || inp.type;
|
||||
@@ -155,11 +165,21 @@ export class EzNodeMenuItem {
|
||||
}
|
||||
|
||||
call(selectNode = true) {
|
||||
if (!this.item?.callback) throw new Error(`Menu Item ${this.item?.content ?? "[null]"} has no callback.`);
|
||||
if (!this.item?.callback)
|
||||
throw new Error(
|
||||
`Menu Item ${this.item?.content ?? "[null]"} has no callback.`
|
||||
);
|
||||
if (selectNode) {
|
||||
this.node.select();
|
||||
}
|
||||
return this.item.callback.call(this.node.node, undefined, undefined, undefined, undefined, this.node.node);
|
||||
return this.item.callback.call(
|
||||
this.node.node,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
this.node.node
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +208,7 @@ export class EzWidget {
|
||||
|
||||
set value(v) {
|
||||
this.widget.value = v;
|
||||
this.widget.callback?.call?.(this.widget, v)
|
||||
this.widget.callback?.call?.(this.widget, v);
|
||||
}
|
||||
|
||||
get isConvertedToInput() {
|
||||
@@ -197,24 +217,35 @@ export class EzWidget {
|
||||
}
|
||||
|
||||
getConvertedInput() {
|
||||
if (!this.isConvertedToInput) throw new Error(`Widget ${this.widget.name} is not converted to input.`);
|
||||
if (!this.isConvertedToInput)
|
||||
throw new Error(`Widget ${this.widget.name} is not converted to input.`);
|
||||
|
||||
return this.node.inputs.find((inp) => inp.input["widget"]?.name === this.widget.name);
|
||||
return this.node.inputs.find(
|
||||
(inp) => inp.input["widget"]?.name === this.widget.name
|
||||
);
|
||||
}
|
||||
|
||||
convertToWidget() {
|
||||
if (!this.isConvertedToInput)
|
||||
throw new Error(`Widget ${this.widget.name} cannot be converted as it is already a widget.`);
|
||||
throw new Error(
|
||||
`Widget ${this.widget.name} cannot be converted as it is already a widget.`
|
||||
);
|
||||
var menu = this.node.menu["Convert Input to Widget"].item.submenu.options;
|
||||
var index = menu.findIndex(a => a.content == `Convert ${this.widget.name} to widget`);
|
||||
var index = menu.findIndex(
|
||||
(a) => a.content == `Convert ${this.widget.name} to widget`
|
||||
);
|
||||
menu[index].callback.call();
|
||||
}
|
||||
|
||||
convertToInput() {
|
||||
if (this.isConvertedToInput)
|
||||
throw new Error(`Widget ${this.widget.name} cannot be converted as it is already an input.`);
|
||||
throw new Error(
|
||||
`Widget ${this.widget.name} cannot be converted as it is already an input.`
|
||||
);
|
||||
var menu = this.node.menu["Convert Widget to Input"].item.submenu.options;
|
||||
var index = menu.findIndex(a => a.content == `Convert ${this.widget.name} to input`);
|
||||
var index = menu.findIndex(
|
||||
(a) => a.content == `Convert ${this.widget.name} to input`
|
||||
);
|
||||
menu[index].callback.call();
|
||||
}
|
||||
}
|
||||
@@ -251,7 +282,11 @@ export class EzNode {
|
||||
}
|
||||
|
||||
get menu() {
|
||||
return this.#makeLookupArray(() => this.app.canvas.getNodeMenuOptions(this.node), "content", EzNodeMenuItem);
|
||||
return this.#makeLookupArray(
|
||||
() => this.app.canvas.getNodeMenuOptions(this.node),
|
||||
"content",
|
||||
EzNodeMenuItem
|
||||
);
|
||||
}
|
||||
|
||||
get isRemoved() {
|
||||
@@ -287,25 +322,33 @@ export class EzNode {
|
||||
* @returns { Record<string, InstanceType<T>> & Array<InstanceType<T>> }
|
||||
*/
|
||||
#makeLookupArray(nodeProperty, nameProperty, ctor) {
|
||||
const items = typeof nodeProperty === "function" ? nodeProperty() : this.node[nodeProperty];
|
||||
const items =
|
||||
typeof nodeProperty === "function"
|
||||
? nodeProperty()
|
||||
: this.node[nodeProperty];
|
||||
// @ts-ignore
|
||||
return (items ?? []).reduce((p, s, i) => {
|
||||
if (!s) return p;
|
||||
return (items ?? []).reduce(
|
||||
(p, s, i) => {
|
||||
if (!s) return p;
|
||||
|
||||
const name = s[nameProperty];
|
||||
const item = new ctor(this, i, s);
|
||||
// @ts-ignore
|
||||
p.push(item);
|
||||
if (name) {
|
||||
const name = s[nameProperty];
|
||||
const item = new ctor(this, i, s);
|
||||
// @ts-ignore
|
||||
if (name in p) {
|
||||
throw new Error(`Unable to store ${nodeProperty} ${name} on array as name conflicts.`);
|
||||
p.push(item);
|
||||
if (name) {
|
||||
// @ts-ignore
|
||||
if (name in p) {
|
||||
throw new Error(
|
||||
`Unable to store ${nodeProperty} ${name} on array as name conflicts.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// @ts-ignore
|
||||
p[name] = item;
|
||||
return p;
|
||||
}, Object.assign([], { $: this }));
|
||||
// @ts-ignore
|
||||
p[name] = item;
|
||||
return p;
|
||||
},
|
||||
Object.assign([], { $: this })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,28 +431,28 @@ export class EzGraph {
|
||||
}
|
||||
|
||||
export const Ez = {
|
||||
/**
|
||||
* Quickly build and interact with a ComfyUI graph
|
||||
* @example
|
||||
* const { ez, graph } = Ez.graph(app);
|
||||
* graph.clear();
|
||||
* const [model, clip, vae] = ez.CheckpointLoaderSimple().outputs;
|
||||
* const [pos] = ez.CLIPTextEncode(clip, { text: "positive" }).outputs;
|
||||
* const [neg] = ez.CLIPTextEncode(clip, { text: "negative" }).outputs;
|
||||
* const [latent] = ez.KSampler(model, pos, neg, ...ez.EmptyLatentImage().outputs).outputs;
|
||||
* const [image] = ez.VAEDecode(latent, vae).outputs;
|
||||
* const saveNode = ez.SaveImage(image);
|
||||
* console.log(saveNode);
|
||||
* graph.arrange();
|
||||
* @param { app } app
|
||||
* @param { boolean } clearGraph
|
||||
* @param { LG["LiteGraph"] } LiteGraph
|
||||
* @param { LG["LGraphCanvas"] } LGraphCanvas
|
||||
* @returns { { graph: EzGraph, ez: Record<string, EzNodeFactory> } }
|
||||
*/
|
||||
graph(app, LiteGraph, LGraphCanvas, clearGraph = true) {
|
||||
// Always set the active canvas so things work
|
||||
LGraphCanvas.active_canvas = app.canvas;
|
||||
/**
|
||||
* Quickly build and interact with a ComfyUI graph
|
||||
* @example
|
||||
* const { ez, graph } = Ez.graph(app);
|
||||
* graph.clear();
|
||||
* const [model, clip, vae] = ez.CheckpointLoaderSimple().outputs;
|
||||
* const [pos] = ez.CLIPTextEncode(clip, { text: "positive" }).outputs;
|
||||
* const [neg] = ez.CLIPTextEncode(clip, { text: "negative" }).outputs;
|
||||
* const [latent] = ez.KSampler(model, pos, neg, ...ez.EmptyLatentImage().outputs).outputs;
|
||||
* const [image] = ez.VAEDecode(latent, vae).outputs;
|
||||
* const saveNode = ez.SaveImage(image);
|
||||
* console.log(saveNode);
|
||||
* graph.arrange();
|
||||
* @param { app } app
|
||||
* @param { boolean } clearGraph
|
||||
* @param { LG["LiteGraph"] } LiteGraph
|
||||
* @param { LG["LGraphCanvas"] } LGraphCanvas
|
||||
* @returns { { graph: EzGraph, ez: Record<string, EzNodeFactory> } }
|
||||
*/
|
||||
graph(app, LiteGraph, LGraphCanvas, clearGraph = true) {
|
||||
// Always set the active canvas so things work
|
||||
LGraphCanvas.active_canvas = app.canvas;
|
||||
|
||||
if (clearGraph) {
|
||||
app.graph.clear();
|
||||
|
||||
@@ -4,7 +4,7 @@ import lg from "./litegraph";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
const html = fs.readFileSync(path.resolve(__dirname, "../../index.html"))
|
||||
const html = fs.readFileSync(path.resolve(__dirname, "../../index.html"));
|
||||
|
||||
interface StartConfig extends APIConfig {
|
||||
resetEnv?: boolean;
|
||||
@@ -20,18 +20,18 @@ interface StartResult {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param { Parameters<typeof mockApi>[0] & {
|
||||
* resetEnv?: boolean,
|
||||
* @param { Parameters<typeof mockApi>[0] & {
|
||||
* resetEnv?: boolean,
|
||||
* preSetup?(app): Promise<void>,
|
||||
* localStorage?: Record<string, string>
|
||||
* localStorage?: Record<string, string>
|
||||
* } } config
|
||||
* @returns
|
||||
*/
|
||||
export async function start(config: StartConfig = {}): Promise<StartResult> {
|
||||
if(config.resetEnv) {
|
||||
if (config.resetEnv) {
|
||||
jest.resetModules();
|
||||
jest.resetAllMocks();
|
||||
lg.setup(global);
|
||||
lg.setup(global);
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
}
|
||||
@@ -39,14 +39,14 @@ export async function start(config: StartConfig = {}): Promise<StartResult> {
|
||||
Object.assign(localStorage, config.localStorage ?? {});
|
||||
document.body.innerHTML = html.toString();
|
||||
|
||||
mockApi(config);
|
||||
const { app } = await import("../../src/scripts/app");
|
||||
const { LiteGraph, LGraphCanvas } = await import("@comfyorg/litegraph");
|
||||
config.preSetup?.(app);
|
||||
await app.setup();
|
||||
mockApi(config);
|
||||
const { app } = await import("../../src/scripts/app");
|
||||
const { LiteGraph, LGraphCanvas } = await import("@comfyorg/litegraph");
|
||||
config.preSetup?.(app);
|
||||
await app.setup();
|
||||
|
||||
// @ts-ignore
|
||||
return { ...Ez.graph(app, LiteGraph, LGraphCanvas), app };
|
||||
// @ts-ignore
|
||||
return { ...Ez.graph(app, LiteGraph, LGraphCanvas), app };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +77,8 @@ export function makeNodeDef(name, input, output = {}) {
|
||||
},
|
||||
};
|
||||
for (const k in input) {
|
||||
nodeDef.input.required[k] = typeof input[k] === "string" ? [input[k], {}] : [...input[k]];
|
||||
nodeDef.input.required[k] =
|
||||
typeof input[k] === "string" ? [input[k], {}] : [...input[k]];
|
||||
}
|
||||
if (output instanceof Array) {
|
||||
output = output.reduce((p, c) => {
|
||||
@@ -143,4 +144,4 @@ export async function getNodeDefs() {
|
||||
|
||||
export async function getNodeDef(nodeId) {
|
||||
return (await getNodeDefs())[nodeId];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,12 @@ function forEachKey(cb) {
|
||||
}
|
||||
|
||||
export default {
|
||||
setup(ctx) {
|
||||
setup(ctx) {},
|
||||
|
||||
},
|
||||
|
||||
teardown(ctx) {
|
||||
// forEachKey((k) => delete ctx[k]);
|
||||
teardown(ctx) {
|
||||
// forEachKey((k) => delete ctx[k]);
|
||||
|
||||
// Clear document after each run
|
||||
document.getElementsByTagName("html")[0].innerHTML = "";
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -17,7 +17,11 @@ export interface APIConfig {
|
||||
mockExtensions?: string[];
|
||||
mockNodeDefs?: Record<string, any>;
|
||||
settings?: Record<string, string>;
|
||||
userConfig?: { storage: "server" | "browser"; users?: Record<string, any>; migrated?: boolean };
|
||||
userConfig?: {
|
||||
storage: "server" | "browser";
|
||||
users?: Record<string, any>;
|
||||
migrated?: boolean;
|
||||
};
|
||||
userData?: Record<string, any>;
|
||||
}
|
||||
|
||||
@@ -29,9 +33,9 @@ export interface APIConfig {
|
||||
* @param {{
|
||||
* mockExtensions?: string[],
|
||||
* mockNodeDefs?: Record<string, ComfyObjectInfo>,
|
||||
* settings?: Record<string, string>
|
||||
* userConfig?: {storage: "server" | "browser", users?: Record<string, any>, migrated?: boolean },
|
||||
* userData?: Record<string, any>
|
||||
* settings?: Record<string, string>
|
||||
* userConfig?: {storage: "server" | "browser", users?: Record<string, any>, migrated?: boolean },
|
||||
* userData?: Record<string, any>
|
||||
* }} config
|
||||
*/
|
||||
export function mockApi(config: APIConfig = {}) {
|
||||
@@ -46,7 +50,9 @@ export function mockApi(config: APIConfig = {}) {
|
||||
.map((x) => path.relative(path.resolve("./src/"), x).replace(/\\/g, "/"));
|
||||
}
|
||||
if (!mockNodeDefs) {
|
||||
mockNodeDefs = JSON.parse(fs.readFileSync(path.resolve("./tests-ui/data/object_info.json")));
|
||||
mockNodeDefs = JSON.parse(
|
||||
fs.readFileSync(path.resolve("./tests-ui/data/object_info.json"))
|
||||
);
|
||||
}
|
||||
|
||||
const events = new EventTarget();
|
||||
@@ -62,14 +68,16 @@ export function mockApi(config: APIConfig = {}) {
|
||||
fileURL: jest.fn((x) => "src/" + x),
|
||||
createUser: jest.fn((username) => {
|
||||
// @ts-ignore
|
||||
if(username in userConfig.users) {
|
||||
return { status: 400, json: () => "Duplicate" }
|
||||
if (username in userConfig.users) {
|
||||
return { status: 400, json: () => "Duplicate" };
|
||||
}
|
||||
// @ts-ignore
|
||||
userConfig.users[username + "!"] = username;
|
||||
return { status: 200, json: () => username + "!" }
|
||||
return { status: 200, json: () => username + "!" };
|
||||
}),
|
||||
getUserConfig: jest.fn(() => userConfig ?? { storage: "browser", migrated: false }),
|
||||
getUserConfig: jest.fn(
|
||||
() => userConfig ?? { storage: "browser", migrated: false }
|
||||
),
|
||||
getSettings: jest.fn(() => settings),
|
||||
storeSettings: jest.fn((v) => Object.assign(settings, v)),
|
||||
getUserData: jest.fn((f) => {
|
||||
|
||||
Reference in New Issue
Block a user