mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-24 16:29:45 +00:00
Apply new code format standard (#217)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { LiteGraph, LGraphCanvas } from "@comfyorg/litegraph";
|
||||
import type { LiteGraph, LGraphCanvas } from '@comfyorg/litegraph'
|
||||
|
||||
/**
|
||||
* @typedef { import("./src/scripts/app")["app"] } app
|
||||
@@ -11,34 +11,28 @@ import type { LiteGraph, LGraphCanvas } from "@comfyorg/litegraph";
|
||||
* @typedef { (...args: EzOutput[] | [...EzOutput[], Record<string, unknown>]) => EzNode } EzNodeFactory
|
||||
*/
|
||||
|
||||
export type EzNameSpace = Record<string, (...args) => EzNode>;
|
||||
export type EzNameSpace = Record<string, (...args) => EzNode>
|
||||
|
||||
export class EzConnection {
|
||||
/** @type { app } */
|
||||
app;
|
||||
app
|
||||
/** @type { InstanceType<LG["LLink"]> } */
|
||||
link;
|
||||
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() {
|
||||
return this.originNode.outputs[this.link.origin_slot];
|
||||
return this.originNode.outputs[this.link.origin_slot]
|
||||
}
|
||||
|
||||
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() {
|
||||
return this.targetNode.inputs[this.link.target_slot];
|
||||
return this.targetNode.inputs[this.link.target_slot]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,34 +40,34 @@ export class EzConnection {
|
||||
* @param { InstanceType<LG["LLink"]> } link
|
||||
*/
|
||||
constructor(app, link) {
|
||||
this.app = app;
|
||||
this.link = link;
|
||||
this.app = app
|
||||
this.link = link
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.targetInput.disconnect();
|
||||
this.targetInput.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
export class EzSlot {
|
||||
/** @type { EzNode } */
|
||||
node;
|
||||
node
|
||||
/** @type { number } */
|
||||
index;
|
||||
index
|
||||
|
||||
/**
|
||||
* @param { EzNode } node
|
||||
* @param { number } index
|
||||
*/
|
||||
constructor(node, index) {
|
||||
this.node = node;
|
||||
this.index = index;
|
||||
this.node = node
|
||||
this.index = index
|
||||
}
|
||||
}
|
||||
|
||||
export class EzInput extends EzSlot {
|
||||
/** @type { INodeInputSlot } */
|
||||
input;
|
||||
input
|
||||
|
||||
/**
|
||||
* @param { EzNode } node
|
||||
@@ -81,26 +75,26 @@ export class EzInput extends EzSlot {
|
||||
* @param { INodeInputSlot } input
|
||||
*/
|
||||
constructor(node, index, input) {
|
||||
super(node, index);
|
||||
this.input = input;
|
||||
super(node, index)
|
||||
this.input = input
|
||||
}
|
||||
|
||||
get connection() {
|
||||
const link = this.node.node.inputs?.[this.index]?.link;
|
||||
const link = this.node.node.inputs?.[this.index]?.link
|
||||
if (link == null) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
return new EzConnection(this.node.app, this.node.app.graph.links[link]);
|
||||
return new EzConnection(this.node.app, this.node.app.graph.links[link])
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.node.node.disconnectInput(this.index);
|
||||
this.node.node.disconnectInput(this.index)
|
||||
}
|
||||
}
|
||||
|
||||
export class EzOutput extends EzSlot {
|
||||
/** @type { INodeOutputSlot } */
|
||||
output;
|
||||
output
|
||||
|
||||
/**
|
||||
* @param { EzNode } node
|
||||
@@ -108,21 +102,21 @@ export class EzOutput extends EzSlot {
|
||||
* @param { INodeOutputSlot } output
|
||||
*/
|
||||
constructor(node, index, output) {
|
||||
super(node, index);
|
||||
this.output = output;
|
||||
super(node, index)
|
||||
this.output = output
|
||||
}
|
||||
|
||||
get connections() {
|
||||
return (this.node.node.outputs?.[this.index]?.links ?? []).map(
|
||||
(l) => new EzConnection(this.node.app, this.node.app.graph.links[l])
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { EzInput } input
|
||||
*/
|
||||
connectTo(input) {
|
||||
if (!input) throw new Error("Invalid input");
|
||||
if (!input) throw new Error('Invalid input')
|
||||
|
||||
/**
|
||||
* @type { LG["LLink"] | null }
|
||||
@@ -131,27 +125,27 @@ export class EzOutput extends EzSlot {
|
||||
this.index,
|
||||
input.node.node,
|
||||
input.index
|
||||
);
|
||||
)
|
||||
if (!link) {
|
||||
const inp = input.input;
|
||||
const inName = inp.name || inp.label || inp.type;
|
||||
const inp = input.input
|
||||
const inName = inp.name || inp.label || inp.type
|
||||
throw new Error(
|
||||
`Connecting from ${input.node.node.type}#${input.node.id}[${inName}#${input.index}] -> ${this.node.node.type}#${this.node.id}[${
|
||||
this.output.name ?? this.output.type
|
||||
}#${this.index}] failed.`
|
||||
);
|
||||
)
|
||||
}
|
||||
return link;
|
||||
return link
|
||||
}
|
||||
}
|
||||
|
||||
export class EzNodeMenuItem {
|
||||
/** @type { EzNode } */
|
||||
node;
|
||||
node
|
||||
/** @type { number } */
|
||||
index;
|
||||
index
|
||||
/** @type { ContextMenuItem } */
|
||||
item;
|
||||
item
|
||||
|
||||
/**
|
||||
* @param { EzNode } node
|
||||
@@ -159,18 +153,18 @@ export class EzNodeMenuItem {
|
||||
* @param { ContextMenuItem } item
|
||||
*/
|
||||
constructor(node, index, item) {
|
||||
this.node = node;
|
||||
this.index = index;
|
||||
this.item = item;
|
||||
this.node = node
|
||||
this.index = index
|
||||
this.item = item
|
||||
}
|
||||
|
||||
call(selectNode = true) {
|
||||
if (!this.item?.callback)
|
||||
throw new Error(
|
||||
`Menu Item ${this.item?.content ?? "[null]"} has no callback.`
|
||||
);
|
||||
`Menu Item ${this.item?.content ?? '[null]'} has no callback.`
|
||||
)
|
||||
if (selectNode) {
|
||||
this.node.select();
|
||||
this.node.select()
|
||||
}
|
||||
return this.item.callback.call(
|
||||
this.node.node,
|
||||
@@ -179,17 +173,17 @@ export class EzNodeMenuItem {
|
||||
undefined,
|
||||
undefined,
|
||||
this.node.node
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class EzWidget {
|
||||
/** @type { EzNode } */
|
||||
node;
|
||||
node
|
||||
/** @type { number } */
|
||||
index;
|
||||
index
|
||||
/** @type { IWidget } */
|
||||
widget;
|
||||
widget
|
||||
|
||||
/**
|
||||
* @param { EzNode } node
|
||||
@@ -197,104 +191,104 @@ export class EzWidget {
|
||||
* @param { IWidget } widget
|
||||
*/
|
||||
constructor(node, index, widget) {
|
||||
this.node = node;
|
||||
this.index = index;
|
||||
this.widget = widget;
|
||||
this.node = node
|
||||
this.index = index
|
||||
this.widget = widget
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.widget.value;
|
||||
return this.widget.value
|
||||
}
|
||||
|
||||
set value(v) {
|
||||
this.widget.value = v;
|
||||
this.widget.callback?.call?.(this.widget, v);
|
||||
this.widget.value = v
|
||||
this.widget.callback?.call?.(this.widget, v)
|
||||
}
|
||||
|
||||
get isConvertedToInput() {
|
||||
// @ts-ignore : this type is valid for converted widgets
|
||||
return this.widget.type === "converted-widget";
|
||||
return this.widget.type === 'converted-widget'
|
||||
}
|
||||
|
||||
getConvertedInput() {
|
||||
if (!this.isConvertedToInput)
|
||||
throw new Error(`Widget ${this.widget.name} is not converted to input.`);
|
||||
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
|
||||
);
|
||||
(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.`
|
||||
);
|
||||
var menu = this.node.menu["Convert Input to Widget"].item.submenu.options;
|
||||
)
|
||||
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`
|
||||
);
|
||||
menu[index].callback.call();
|
||||
)
|
||||
menu[index].callback.call()
|
||||
}
|
||||
|
||||
convertToInput() {
|
||||
if (this.isConvertedToInput)
|
||||
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 menu = this.node.menu['Convert Widget to Input'].item.submenu.options
|
||||
var index = menu.findIndex(
|
||||
(a) => a.content == `Convert ${this.widget.name} to input`
|
||||
);
|
||||
menu[index].callback.call();
|
||||
)
|
||||
menu[index].callback.call()
|
||||
}
|
||||
}
|
||||
|
||||
export class EzNode {
|
||||
/** @type { app } */
|
||||
app;
|
||||
app
|
||||
/** @type { LGNode } */
|
||||
node;
|
||||
node
|
||||
|
||||
/**
|
||||
* @param { app } app
|
||||
* @param { LGNode } node
|
||||
*/
|
||||
constructor(app, node) {
|
||||
this.app = app;
|
||||
this.node = node;
|
||||
this.app = app
|
||||
this.node = node
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this.node.id;
|
||||
return this.node.id
|
||||
}
|
||||
|
||||
get inputs() {
|
||||
return this.#makeLookupArray("inputs", "name", EzInput);
|
||||
return this.#makeLookupArray('inputs', 'name', EzInput)
|
||||
}
|
||||
|
||||
get outputs() {
|
||||
return this.#makeLookupArray("outputs", "name", EzOutput);
|
||||
return this.#makeLookupArray('outputs', 'name', EzOutput)
|
||||
}
|
||||
|
||||
get widgets() {
|
||||
return this.#makeLookupArray("widgets", "name", EzWidget);
|
||||
return this.#makeLookupArray('widgets', 'name', EzWidget)
|
||||
}
|
||||
|
||||
get menu() {
|
||||
return this.#makeLookupArray(
|
||||
() => this.app.canvas.getNodeMenuOptions(this.node),
|
||||
"content",
|
||||
'content',
|
||||
EzNodeMenuItem
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
get isRemoved() {
|
||||
return !this.app.graph.getNodeById(this.id);
|
||||
return !this.app.graph.getNodeById(this.id)
|
||||
}
|
||||
|
||||
select(addToSelection = false) {
|
||||
this.app.canvas.selectNode(this.node, addToSelection);
|
||||
this.app.canvas.selectNode(this.node, addToSelection)
|
||||
}
|
||||
|
||||
// /**
|
||||
@@ -323,60 +317,60 @@ export class EzNode {
|
||||
*/
|
||||
#makeLookupArray(nodeProperty, nameProperty, ctor) {
|
||||
const items =
|
||||
typeof nodeProperty === "function"
|
||||
typeof nodeProperty === 'function'
|
||||
? nodeProperty()
|
||||
: this.node[nodeProperty];
|
||||
: this.node[nodeProperty]
|
||||
// @ts-ignore
|
||||
return (items ?? []).reduce(
|
||||
(p, s, i) => {
|
||||
if (!s) return p;
|
||||
if (!s) return p
|
||||
|
||||
const name = s[nameProperty];
|
||||
const item = new ctor(this, i, s);
|
||||
const name = s[nameProperty]
|
||||
const item = new ctor(this, i, s)
|
||||
// @ts-ignore
|
||||
p.push(item);
|
||||
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;
|
||||
p[name] = item
|
||||
return p
|
||||
},
|
||||
Object.assign([], { $: this })
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class EzGraph {
|
||||
/** @type { app } */
|
||||
app;
|
||||
app
|
||||
|
||||
/**
|
||||
* @param { app } app
|
||||
*/
|
||||
constructor(app) {
|
||||
this.app = app;
|
||||
this.app = app
|
||||
}
|
||||
|
||||
get nodes() {
|
||||
return this.app.graph._nodes.map((n) => new EzNode(this.app, n));
|
||||
return this.app.graph._nodes.map((n) => new EzNode(this.app, n))
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.app.graph.clear();
|
||||
this.app.graph.clear()
|
||||
}
|
||||
|
||||
arrange() {
|
||||
this.app.graph.arrange();
|
||||
this.app.graph.arrange()
|
||||
}
|
||||
|
||||
stringify() {
|
||||
return JSON.stringify(this.app.graph.serialize(), undefined);
|
||||
return JSON.stringify(this.app.graph.serialize(), undefined)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -384,36 +378,36 @@ export class EzGraph {
|
||||
* @returns { EzNode }
|
||||
*/
|
||||
find(obj) {
|
||||
let match;
|
||||
let id;
|
||||
if (typeof obj === "number") {
|
||||
id = obj;
|
||||
let match
|
||||
let id
|
||||
if (typeof obj === 'number') {
|
||||
id = obj
|
||||
} else {
|
||||
id = obj.id;
|
||||
id = obj.id
|
||||
}
|
||||
|
||||
match = this.app.graph.getNodeById(id);
|
||||
match = this.app.graph.getNodeById(id)
|
||||
|
||||
if (!match) {
|
||||
throw new Error(`Unable to find node with ID ${id}.`);
|
||||
throw new Error(`Unable to find node with ID ${id}.`)
|
||||
}
|
||||
|
||||
return new EzNode(this.app, match);
|
||||
return new EzNode(this.app, match)
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
reload() {
|
||||
const graph = JSON.parse(JSON.stringify(this.app.graph.serialize()));
|
||||
const graph = JSON.parse(JSON.stringify(this.app.graph.serialize()))
|
||||
return new Promise((r) => {
|
||||
this.app.graph.clear();
|
||||
this.app.graph.clear()
|
||||
setTimeout(async () => {
|
||||
await this.app.loadGraphData(graph);
|
||||
await this.app.loadGraphData(graph)
|
||||
// @ts-ignore
|
||||
r();
|
||||
}, 10);
|
||||
});
|
||||
r()
|
||||
}, 10)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -426,7 +420,7 @@ export class EzGraph {
|
||||
*/
|
||||
toPrompt() {
|
||||
// @ts-ignore
|
||||
return this.app.graphToPrompt();
|
||||
return this.app.graphToPrompt()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,10 +446,10 @@ export const Ez = {
|
||||
*/
|
||||
graph(app, LiteGraph, LGraphCanvas, clearGraph = true) {
|
||||
// Always set the active canvas so things work
|
||||
LGraphCanvas.active_canvas = app.canvas;
|
||||
LGraphCanvas.active_canvas = app.canvas
|
||||
|
||||
if (clearGraph) {
|
||||
app.graph.clear();
|
||||
app.graph.clear()
|
||||
}
|
||||
|
||||
// @ts-ignore : this proxy handles utility methods & node creation
|
||||
@@ -463,35 +457,35 @@ export const Ez = {
|
||||
{},
|
||||
{
|
||||
get(_, p) {
|
||||
if (typeof p !== "string") throw new Error("Invalid node");
|
||||
const node = LiteGraph.createNode(p);
|
||||
if (!node) throw new Error(`Unknown node "${p}"`);
|
||||
app.graph.add(node);
|
||||
if (typeof p !== 'string') throw new Error('Invalid node')
|
||||
const node = LiteGraph.createNode(p)
|
||||
if (!node) throw new Error(`Unknown node "${p}"`)
|
||||
app.graph.add(node)
|
||||
|
||||
/**
|
||||
* @param {Parameters<EzNodeFactory>} args
|
||||
*/
|
||||
return function (...args) {
|
||||
const ezNode = new EzNode(app, node);
|
||||
const inputs = ezNode.inputs;
|
||||
const ezNode = new EzNode(app, node)
|
||||
const inputs = ezNode.inputs
|
||||
|
||||
let slot = 0;
|
||||
let slot = 0
|
||||
for (const arg of args) {
|
||||
if (arg instanceof EzOutput) {
|
||||
arg.connectTo(inputs[slot++]);
|
||||
arg.connectTo(inputs[slot++])
|
||||
} else {
|
||||
for (const k in arg) {
|
||||
ezNode.widgets[k].value = arg[k];
|
||||
ezNode.widgets[k].value = arg[k]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ezNode;
|
||||
};
|
||||
},
|
||||
return ezNode
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
return { graph: new EzGraph(app), ez: factory };
|
||||
},
|
||||
};
|
||||
return { graph: new EzGraph(app), ez: factory }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import { APIConfig, mockApi } from "./setup";
|
||||
import { Ez, EzGraph, EzNameSpace } from "./ezgraph";
|
||||
import lg from "./litegraph";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { APIConfig, mockApi } from './setup'
|
||||
import { Ez, EzGraph, EzNameSpace } from './ezgraph'
|
||||
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;
|
||||
preSetup?(app): Promise<void>;
|
||||
localStorage?: Record<string, string>;
|
||||
resetEnv?: boolean
|
||||
preSetup?(app): Promise<void>
|
||||
localStorage?: Record<string, string>
|
||||
}
|
||||
|
||||
interface StartResult {
|
||||
app: any;
|
||||
graph: EzGraph;
|
||||
ez: EzNameSpace;
|
||||
app: any
|
||||
graph: EzGraph
|
||||
ez: EzNameSpace
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,24 +29,24 @@ interface StartResult {
|
||||
*/
|
||||
export async function start(config: StartConfig = {}): Promise<StartResult> {
|
||||
if (config.resetEnv) {
|
||||
jest.resetModules();
|
||||
jest.resetAllMocks();
|
||||
lg.setup(global);
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
jest.resetModules()
|
||||
jest.resetAllMocks()
|
||||
lg.setup(global)
|
||||
localStorage.clear()
|
||||
sessionStorage.clear()
|
||||
}
|
||||
|
||||
Object.assign(localStorage, config.localStorage ?? {});
|
||||
document.body.innerHTML = html.toString();
|
||||
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 };
|
||||
return { ...Ez.graph(app, LiteGraph, LGraphCanvas), app }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,9 +54,9 @@ export async function start(config: StartConfig = {}): Promise<StartResult> {
|
||||
* @param { (hasReloaded: boolean) => (Promise<void> | void) } cb
|
||||
*/
|
||||
export async function checkBeforeAndAfterReload(graph, cb) {
|
||||
await cb(false);
|
||||
await graph.reload();
|
||||
await cb(true);
|
||||
await cb(false)
|
||||
await graph.reload()
|
||||
await cb(true)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,34 +68,34 @@ export async function checkBeforeAndAfterReload(graph, cb) {
|
||||
export function makeNodeDef(name, input, output = {}) {
|
||||
const nodeDef = {
|
||||
name,
|
||||
category: "test",
|
||||
category: 'test',
|
||||
output: [],
|
||||
output_name: [],
|
||||
output_is_list: [],
|
||||
input: {
|
||||
required: {},
|
||||
},
|
||||
};
|
||||
required: {}
|
||||
}
|
||||
}
|
||||
for (const k in input) {
|
||||
nodeDef.input.required[k] =
|
||||
typeof input[k] === "string" ? [input[k], {}] : [...input[k]];
|
||||
typeof input[k] === 'string' ? [input[k], {}] : [...input[k]]
|
||||
}
|
||||
if (output instanceof Array) {
|
||||
output = output.reduce((p, c) => {
|
||||
p[c] = c;
|
||||
return p;
|
||||
}, {});
|
||||
p[c] = c
|
||||
return p
|
||||
}, {})
|
||||
}
|
||||
for (const k in output) {
|
||||
// @ts-ignore
|
||||
nodeDef.output.push(output[k]);
|
||||
nodeDef.output.push(output[k])
|
||||
// @ts-ignore
|
||||
nodeDef.output_name.push(k);
|
||||
nodeDef.output_name.push(k)
|
||||
// @ts-ignore
|
||||
nodeDef.output_is_list.push(false);
|
||||
nodeDef.output_is_list.push(false)
|
||||
}
|
||||
|
||||
return { [name]: nodeDef };
|
||||
return { [name]: nodeDef }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,9 +105,9 @@ export function makeNodeDef(name, input, output = {}) {
|
||||
* @returns { x is Exclude<T, null | undefined> }
|
||||
*/
|
||||
export function assertNotNullOrUndefined(x) {
|
||||
expect(x).not.toEqual(null);
|
||||
expect(x).not.toEqual(undefined);
|
||||
return true;
|
||||
expect(x).not.toEqual(null)
|
||||
expect(x).not.toEqual(undefined)
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,32 +116,32 @@ export function assertNotNullOrUndefined(x) {
|
||||
* @param { ReturnType<Ez["graph"]>["graph"] } graph
|
||||
*/
|
||||
export function createDefaultWorkflow(ez, graph) {
|
||||
graph.clear();
|
||||
const ckpt = ez.CheckpointLoaderSimple();
|
||||
graph.clear()
|
||||
const ckpt = ez.CheckpointLoaderSimple()
|
||||
|
||||
const pos = ez.CLIPTextEncode(ckpt.outputs.CLIP, { text: "positive" });
|
||||
const neg = ez.CLIPTextEncode(ckpt.outputs.CLIP, { text: "negative" });
|
||||
const pos = ez.CLIPTextEncode(ckpt.outputs.CLIP, { text: 'positive' })
|
||||
const neg = ez.CLIPTextEncode(ckpt.outputs.CLIP, { text: 'negative' })
|
||||
|
||||
const empty = ez.EmptyLatentImage();
|
||||
const empty = ez.EmptyLatentImage()
|
||||
const sampler = ez.KSampler(
|
||||
ckpt.outputs.MODEL,
|
||||
pos.outputs.CONDITIONING,
|
||||
neg.outputs.CONDITIONING,
|
||||
empty.outputs.LATENT
|
||||
);
|
||||
)
|
||||
|
||||
const decode = ez.VAEDecode(sampler.outputs.LATENT, ckpt.outputs.VAE);
|
||||
const save = ez.SaveImage(decode.outputs.IMAGE);
|
||||
graph.arrange();
|
||||
const decode = ez.VAEDecode(sampler.outputs.LATENT, ckpt.outputs.VAE)
|
||||
const save = ez.SaveImage(decode.outputs.IMAGE)
|
||||
graph.arrange()
|
||||
|
||||
return { ckpt, pos, neg, empty, sampler, decode, save };
|
||||
return { ckpt, pos, neg, empty, sampler, decode, save }
|
||||
}
|
||||
|
||||
export async function getNodeDefs() {
|
||||
const { api } = await import("../../src/scripts/api");
|
||||
return api.getNodeDefs();
|
||||
const { api } = await import('../../src/scripts/api')
|
||||
return api.getNodeDefs()
|
||||
}
|
||||
|
||||
export async function getNodeDef(nodeId) {
|
||||
return (await getNodeDefs())[nodeId];
|
||||
return (await getNodeDefs())[nodeId]
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { nop } from "../utils/nopProxy";
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { nop } from '../utils/nopProxy'
|
||||
|
||||
function forEachKey(cb) {
|
||||
for (const k of [
|
||||
"LiteGraph",
|
||||
"LGraph",
|
||||
"LLink",
|
||||
"LGraphNode",
|
||||
"LGraphGroup",
|
||||
"DragAndScale",
|
||||
"LGraphCanvas",
|
||||
"ContextMenu",
|
||||
'LiteGraph',
|
||||
'LGraph',
|
||||
'LLink',
|
||||
'LGraphNode',
|
||||
'LGraphGroup',
|
||||
'DragAndScale',
|
||||
'LGraphCanvas',
|
||||
'ContextMenu'
|
||||
]) {
|
||||
cb(k);
|
||||
cb(k)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,6 @@ export default {
|
||||
// forEachKey((k) => delete ctx[k]);
|
||||
|
||||
// Clear document after each run
|
||||
document.getElementsByTagName("html")[0].innerHTML = "";
|
||||
},
|
||||
};
|
||||
document.getElementsByTagName('html')[0].innerHTML = ''
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ export const nop = new Proxy(function () {}, {
|
||||
get: () => nop,
|
||||
set: () => true,
|
||||
apply: () => nop,
|
||||
construct: () => nop,
|
||||
});
|
||||
construct: () => nop
|
||||
})
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import "../../src/scripts/api";
|
||||
import '../../src/scripts/api'
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
function* walkSync(dir: string): Generator<string> {
|
||||
const files = fs.readdirSync(dir, { withFileTypes: true });
|
||||
const files = fs.readdirSync(dir, { withFileTypes: true })
|
||||
for (const file of files) {
|
||||
if (file.isDirectory()) {
|
||||
yield* walkSync(path.join(dir, file.name));
|
||||
yield* walkSync(path.join(dir, file.name))
|
||||
} else {
|
||||
yield path.join(dir, file.name);
|
||||
yield path.join(dir, file.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface APIConfig {
|
||||
mockExtensions?: string[];
|
||||
mockNodeDefs?: Record<string, any>;
|
||||
settings?: Record<string, string>;
|
||||
mockExtensions?: string[]
|
||||
mockNodeDefs?: Record<string, any>
|
||||
settings?: Record<string, string>
|
||||
userConfig?: {
|
||||
storage: "server" | "browser";
|
||||
users?: Record<string, any>;
|
||||
migrated?: boolean;
|
||||
};
|
||||
userData?: Record<string, any>;
|
||||
storage: 'server' | 'browser'
|
||||
users?: Record<string, any>
|
||||
migrated?: boolean
|
||||
}
|
||||
userData?: Record<string, any>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,20 +42,20 @@ export function mockApi(config: APIConfig = {}) {
|
||||
let { mockExtensions, mockNodeDefs, userConfig, settings, userData } = {
|
||||
settings: {},
|
||||
userData: {},
|
||||
...config,
|
||||
};
|
||||
...config
|
||||
}
|
||||
if (!mockExtensions) {
|
||||
mockExtensions = Array.from(walkSync(path.resolve("./src/extensions/core")))
|
||||
.filter((x) => x.endsWith(".js"))
|
||||
.map((x) => path.relative(path.resolve("./src/"), x).replace(/\\/g, "/"));
|
||||
mockExtensions = Array.from(walkSync(path.resolve('./src/extensions/core')))
|
||||
.filter((x) => x.endsWith('.js'))
|
||||
.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"))
|
||||
);
|
||||
fs.readFileSync(path.resolve('./tests-ui/data/object_info.json'))
|
||||
)
|
||||
}
|
||||
|
||||
const events = new EventTarget();
|
||||
const events = new EventTarget()
|
||||
const mockApi = {
|
||||
addEventListener: events.addEventListener.bind(events),
|
||||
removeEventListener: events.removeEventListener.bind(events),
|
||||
@@ -64,37 +64,37 @@ export function mockApi(config: APIConfig = {}) {
|
||||
getExtensions: jest.fn(() => mockExtensions),
|
||||
getNodeDefs: jest.fn(() => mockNodeDefs),
|
||||
init: jest.fn(),
|
||||
apiURL: jest.fn((x) => "src/" + x),
|
||||
fileURL: jest.fn((x) => "src/" + x),
|
||||
apiURL: jest.fn((x) => 'src/' + x),
|
||||
fileURL: jest.fn((x) => 'src/' + x),
|
||||
createUser: jest.fn((username) => {
|
||||
// @ts-ignore
|
||||
if (username in userConfig.users) {
|
||||
return { status: 400, json: () => "Duplicate" };
|
||||
return { status: 400, json: () => 'Duplicate' }
|
||||
}
|
||||
// @ts-ignore
|
||||
userConfig.users[username + "!"] = username;
|
||||
return { status: 200, json: () => username + "!" };
|
||||
userConfig.users[username + '!'] = username
|
||||
return { status: 200, json: () => username + '!' }
|
||||
}),
|
||||
getUserConfig: jest.fn(
|
||||
() => userConfig ?? { storage: "browser", migrated: false }
|
||||
() => userConfig ?? { storage: 'browser', migrated: false }
|
||||
),
|
||||
getSettings: jest.fn(() => settings),
|
||||
storeSettings: jest.fn((v) => Object.assign(settings, v)),
|
||||
getUserData: jest.fn((f) => {
|
||||
if (f in userData) {
|
||||
return { status: 200, json: () => userData[f] };
|
||||
return { status: 200, json: () => userData[f] }
|
||||
} else {
|
||||
return { status: 404 };
|
||||
return { status: 404 }
|
||||
}
|
||||
}),
|
||||
storeUserData: jest.fn((file, data) => {
|
||||
userData[file] = data;
|
||||
userData[file] = data
|
||||
}),
|
||||
listUserData: jest.fn(() => []),
|
||||
};
|
||||
jest.mock("../../src/scripts/api", () => ({
|
||||
listUserData: jest.fn(() => [])
|
||||
}
|
||||
jest.mock('../../src/scripts/api', () => ({
|
||||
get api() {
|
||||
return mockApi;
|
||||
},
|
||||
}));
|
||||
return mockApi
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user