mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-28 02:34:10 +00:00
Format all code / Add pre-commit format hook (#81)
* Add format-guard * Format code
This commit is contained in:
@@ -7,107 +7,113 @@ const zQueueIndex = z.number();
|
||||
const zPromptId = z.string();
|
||||
|
||||
const zPromptItem = z.object({
|
||||
inputs: z.record(z.string(), z.any()),
|
||||
class_type: zNodeType,
|
||||
inputs: z.record(z.string(), z.any()),
|
||||
class_type: zNodeType,
|
||||
});
|
||||
|
||||
const zPrompt = z.array(zPromptItem);
|
||||
|
||||
const zExtraPngInfo = z.object({
|
||||
const zExtraPngInfo = z
|
||||
.object({
|
||||
workflow: zComfyWorkflow,
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const zExtraData = z.object({
|
||||
extra_pnginfo: zExtraPngInfo,
|
||||
client_id: z.string(),
|
||||
extra_pnginfo: zExtraPngInfo,
|
||||
client_id: z.string(),
|
||||
});
|
||||
const zOutputsToExecute = z.array(zNodeId);
|
||||
|
||||
const zExecutionStartMessage = z.tuple([
|
||||
z.literal("execution_start"),
|
||||
z.object({
|
||||
prompt_id: zPromptId,
|
||||
}),
|
||||
z.literal("execution_start"),
|
||||
z.object({
|
||||
prompt_id: zPromptId,
|
||||
}),
|
||||
]);
|
||||
|
||||
const zExecutionCachedMessage = z.tuple([
|
||||
z.literal("execution_cached"),
|
||||
z.object({
|
||||
prompt_id: zPromptId,
|
||||
nodes: z.array(zNodeId),
|
||||
}),
|
||||
z.literal("execution_cached"),
|
||||
z.object({
|
||||
prompt_id: zPromptId,
|
||||
nodes: z.array(zNodeId),
|
||||
}),
|
||||
]);
|
||||
|
||||
const zExecutionInterruptedMessage = z.tuple([
|
||||
z.literal("execution_interrupted"),
|
||||
z.object({
|
||||
// InterruptProcessingException
|
||||
prompt_id: zPromptId,
|
||||
node_id: zNodeId,
|
||||
node_type: zNodeType,
|
||||
executed: z.array(zNodeId),
|
||||
}),
|
||||
z.literal("execution_interrupted"),
|
||||
z.object({
|
||||
// InterruptProcessingException
|
||||
prompt_id: zPromptId,
|
||||
node_id: zNodeId,
|
||||
node_type: zNodeType,
|
||||
executed: z.array(zNodeId),
|
||||
}),
|
||||
]);
|
||||
|
||||
const zExecutionErrorMessage = z.tuple([
|
||||
z.literal("execution_error"),
|
||||
z.object({
|
||||
prompt_id: zPromptId,
|
||||
node_id: zNodeId,
|
||||
node_type: zNodeType,
|
||||
executed: z.array(zNodeId),
|
||||
z.literal("execution_error"),
|
||||
z.object({
|
||||
prompt_id: zPromptId,
|
||||
node_id: zNodeId,
|
||||
node_type: zNodeType,
|
||||
executed: z.array(zNodeId),
|
||||
|
||||
exception_message: z.string(),
|
||||
exception_type: z.string(),
|
||||
traceback: z.string(),
|
||||
current_inputs: z.any(),
|
||||
current_outputs: z.any(),
|
||||
}),
|
||||
exception_message: z.string(),
|
||||
exception_type: z.string(),
|
||||
traceback: z.string(),
|
||||
current_inputs: z.any(),
|
||||
current_outputs: z.any(),
|
||||
}),
|
||||
]);
|
||||
|
||||
const zStatusMessage = z.union([
|
||||
zExecutionStartMessage,
|
||||
zExecutionCachedMessage,
|
||||
zExecutionInterruptedMessage,
|
||||
zExecutionErrorMessage,
|
||||
zExecutionStartMessage,
|
||||
zExecutionCachedMessage,
|
||||
zExecutionInterruptedMessage,
|
||||
zExecutionErrorMessage,
|
||||
]);
|
||||
|
||||
const zStatus = z.object({
|
||||
status_str: z.enum(["success", "error"]),
|
||||
completed: z.boolean(),
|
||||
messages: z.array(zStatusMessage),
|
||||
status_str: z.enum(["success", "error"]),
|
||||
completed: z.boolean(),
|
||||
messages: z.array(zStatusMessage),
|
||||
});
|
||||
|
||||
// TODO: this is a placeholder
|
||||
const zOutput = z.any();
|
||||
|
||||
const zTaskPrompt = z.tuple([
|
||||
zQueueIndex,
|
||||
zPromptId,
|
||||
zPrompt,
|
||||
zExtraData,
|
||||
zOutputsToExecute,
|
||||
zQueueIndex,
|
||||
zPromptId,
|
||||
zPrompt,
|
||||
zExtraData,
|
||||
zOutputsToExecute,
|
||||
]);
|
||||
|
||||
const zRunningTaskItem = z.object({
|
||||
prompt: zTaskPrompt,
|
||||
remove: z.object({
|
||||
name: z.literal("Cancel"),
|
||||
cb: z.function(),
|
||||
}),
|
||||
prompt: zTaskPrompt,
|
||||
remove: z.object({
|
||||
name: z.literal("Cancel"),
|
||||
cb: z.function(),
|
||||
}),
|
||||
});
|
||||
|
||||
const zPendingTaskItem = z.object({
|
||||
prompt: zTaskPrompt,
|
||||
prompt: zTaskPrompt,
|
||||
});
|
||||
|
||||
const zHistoryTaskItem = z.object({
|
||||
prompt: zTaskPrompt,
|
||||
status: zStatus.optional(),
|
||||
outputs: z.record(zNodeId, zOutput),
|
||||
prompt: zTaskPrompt,
|
||||
status: zStatus.optional(),
|
||||
outputs: z.record(zNodeId, zOutput),
|
||||
});
|
||||
|
||||
const zTaskItem = z.union([zRunningTaskItem, zPendingTaskItem, zHistoryTaskItem]);
|
||||
const zTaskItem = z.union([
|
||||
zRunningTaskItem,
|
||||
zPendingTaskItem,
|
||||
zHistoryTaskItem,
|
||||
]);
|
||||
|
||||
// `/queue`
|
||||
export type RunningTaskItem = z.infer<typeof zRunningTaskItem>;
|
||||
@@ -119,101 +125,100 @@ export type TaskItem = z.infer<typeof zTaskItem>;
|
||||
// TODO: validate `/history` `/queue` API endpoint responses.
|
||||
|
||||
function inputSpec(spec: [ZodType, ZodType]): ZodType {
|
||||
const [inputType, inputSpec] = spec;
|
||||
return z.union([
|
||||
z.tuple([inputType, inputSpec]),
|
||||
z.tuple([inputType]),
|
||||
]);
|
||||
const [inputType, inputSpec] = spec;
|
||||
return z.union([z.tuple([inputType, inputSpec]), z.tuple([inputType])]);
|
||||
}
|
||||
|
||||
const zIntInputSpec = inputSpec([
|
||||
z.literal("INT"),
|
||||
z.object({
|
||||
min: z.number().optional(),
|
||||
max: z.number().optional(),
|
||||
step: z.number().optional(),
|
||||
default: z.number().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
z.literal("INT"),
|
||||
z.object({
|
||||
min: z.number().optional(),
|
||||
max: z.number().optional(),
|
||||
step: z.number().optional(),
|
||||
default: z.number().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
]);
|
||||
|
||||
const zFloatInputSpec = inputSpec([
|
||||
z.literal("FLOAT"),
|
||||
z.object({
|
||||
min: z.number().optional(),
|
||||
max: z.number().optional(),
|
||||
step: z.number().optional(),
|
||||
round: z.number().optional(),
|
||||
default: z.number().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
z.literal("FLOAT"),
|
||||
z.object({
|
||||
min: z.number().optional(),
|
||||
max: z.number().optional(),
|
||||
step: z.number().optional(),
|
||||
round: z.number().optional(),
|
||||
default: z.number().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
]);
|
||||
|
||||
const zBooleanInputSpec = inputSpec([
|
||||
z.literal("BOOLEAN"),
|
||||
z.object({
|
||||
label_on: z.string().optional(),
|
||||
label_off: z.string().optional(),
|
||||
default: z.boolean().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
})
|
||||
z.literal("BOOLEAN"),
|
||||
z.object({
|
||||
label_on: z.string().optional(),
|
||||
label_off: z.string().optional(),
|
||||
default: z.boolean().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
]);
|
||||
|
||||
const zStringInputSpec = inputSpec([
|
||||
z.literal("STRING"),
|
||||
z.object({
|
||||
default: z.string().optional(),
|
||||
multiline: z.boolean().optional(),
|
||||
dynamicPrompts: z.boolean().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
z.literal("STRING"),
|
||||
z.object({
|
||||
default: z.string().optional(),
|
||||
multiline: z.boolean().optional(),
|
||||
dynamicPrompts: z.boolean().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
]);
|
||||
|
||||
// Dropdown Selection.
|
||||
const zComboInputSpec = inputSpec([
|
||||
z.array(z.any()),
|
||||
z.object({
|
||||
default: z.any().optional(),
|
||||
control_after_generate: z.boolean().optional(),
|
||||
image_upload: z.boolean().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
z.array(z.any()),
|
||||
z.object({
|
||||
default: z.any().optional(),
|
||||
control_after_generate: z.boolean().optional(),
|
||||
image_upload: z.boolean().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
]);
|
||||
|
||||
const zCustomInputSpec = inputSpec([
|
||||
z.string(),
|
||||
z.object({
|
||||
default: z.any().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
z.string(),
|
||||
z.object({
|
||||
default: z.any().optional(),
|
||||
forceInput: z.boolean().optional(),
|
||||
}),
|
||||
]);
|
||||
|
||||
const zInputSpec = z.union([
|
||||
zIntInputSpec,
|
||||
zFloatInputSpec,
|
||||
zBooleanInputSpec,
|
||||
zStringInputSpec,
|
||||
zComboInputSpec,
|
||||
zCustomInputSpec,
|
||||
zIntInputSpec,
|
||||
zFloatInputSpec,
|
||||
zBooleanInputSpec,
|
||||
zStringInputSpec,
|
||||
zComboInputSpec,
|
||||
zCustomInputSpec,
|
||||
]);
|
||||
|
||||
const zComfyNodeDataType = z.string();
|
||||
const zComfyComboOutput = z.array(z.any());
|
||||
const zComfyOutputSpec = z.array(z.union([zComfyNodeDataType, zComfyComboOutput]));
|
||||
const zComfyOutputSpec = z.array(
|
||||
z.union([zComfyNodeDataType, zComfyComboOutput])
|
||||
);
|
||||
|
||||
const zComfyNodeDef = z.object({
|
||||
input: z.object({
|
||||
required: z.record(zInputSpec).optional(),
|
||||
optional: z.record(zInputSpec).optional(),
|
||||
}),
|
||||
output: zComfyOutputSpec,
|
||||
output_is_list: z.array(z.boolean()),
|
||||
output_name: z.array(z.string()),
|
||||
name: z.string(),
|
||||
display_name: z.string(),
|
||||
description: z.string(),
|
||||
category: z.string(),
|
||||
output_node: z.boolean(),
|
||||
input: z.object({
|
||||
required: z.record(zInputSpec).optional(),
|
||||
optional: z.record(zInputSpec).optional(),
|
||||
}),
|
||||
output: zComfyOutputSpec,
|
||||
output_is_list: z.array(z.boolean()),
|
||||
output_name: z.array(z.string()),
|
||||
name: z.string(),
|
||||
display_name: z.string(),
|
||||
description: z.string(),
|
||||
category: z.string(),
|
||||
output_node: z.boolean(),
|
||||
});
|
||||
|
||||
// `/object_info`
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
import { z } from "zod";
|
||||
|
||||
const nodeSlotSchema = z.object({
|
||||
const nodeSlotSchema = z
|
||||
.object({
|
||||
BOOLEAN: z.string().optional(),
|
||||
CLIP: z.string(),
|
||||
CLIP_VISION: z.string(),
|
||||
@@ -25,10 +26,12 @@ const nodeSlotSchema = z.object({
|
||||
TAESD: z.string(),
|
||||
TIMESTEP_KEYFRAME: z.string().optional(),
|
||||
UPSCALE_MODEL: z.string().optional(),
|
||||
VAE: z.string()
|
||||
}).passthrough();
|
||||
VAE: z.string(),
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const litegraphBaseSchema = z.object({
|
||||
const litegraphBaseSchema = z
|
||||
.object({
|
||||
BACKGROUND_IMAGE: z.string(),
|
||||
CLEAR_BACKGROUND_COLOR: z.string(),
|
||||
NODE_TITLE_COLOR: z.string(),
|
||||
@@ -49,37 +52,40 @@ const litegraphBaseSchema = z.object({
|
||||
WIDGET_SECONDARY_TEXT_COLOR: z.string(),
|
||||
LINK_COLOR: z.string(),
|
||||
EVENT_LINK_COLOR: z.string(),
|
||||
CONNECTING_LINK_COLOR: z.string()
|
||||
}).passthrough();
|
||||
CONNECTING_LINK_COLOR: z.string(),
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const comfyBaseSchema = z.object({
|
||||
["fg-color"]: z.string(),
|
||||
["bg-color"]: z.string(),
|
||||
["comfy-menu-bg"]: z.string(),
|
||||
["comfy-input-bg"]: z.string(),
|
||||
["input-text"]: z.string(),
|
||||
["descrip-text"]: z.string(),
|
||||
["drag-text"]: z.string(),
|
||||
["error-text"]: z.string(),
|
||||
["border-color"]: z.string(),
|
||||
["tr-even-bg-color"]: z.string(),
|
||||
["tr-odd-bg-color"]: z.string(),
|
||||
["content-bg"]: z.string(),
|
||||
["content-fg"]: z.string(),
|
||||
["content-hover-bg"]: z.string(),
|
||||
["content-hover-fg"]: z.string(),
|
||||
["fg-color"]: z.string(),
|
||||
["bg-color"]: z.string(),
|
||||
["comfy-menu-bg"]: z.string(),
|
||||
["comfy-input-bg"]: z.string(),
|
||||
["input-text"]: z.string(),
|
||||
["descrip-text"]: z.string(),
|
||||
["drag-text"]: z.string(),
|
||||
["error-text"]: z.string(),
|
||||
["border-color"]: z.string(),
|
||||
["tr-even-bg-color"]: z.string(),
|
||||
["tr-odd-bg-color"]: z.string(),
|
||||
["content-bg"]: z.string(),
|
||||
["content-fg"]: z.string(),
|
||||
["content-hover-bg"]: z.string(),
|
||||
["content-hover-fg"]: z.string(),
|
||||
});
|
||||
|
||||
const colorsSchema = z.object({
|
||||
const colorsSchema = z
|
||||
.object({
|
||||
node_slot: nodeSlotSchema,
|
||||
litegraph_base: litegraphBaseSchema,
|
||||
comfy_base: comfyBaseSchema
|
||||
}).passthrough();
|
||||
comfy_base: comfyBaseSchema,
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const paletteSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
colors: colorsSchema
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
colors: colorsSchema,
|
||||
});
|
||||
|
||||
const colorPalettesSchema = z.record(paletteSchema);
|
||||
|
||||
147
src/types/comfy.d.ts
vendored
147
src/types/comfy.d.ts
vendored
@@ -2,75 +2,90 @@ import { LGraphNode, IWidget } from "./litegraph";
|
||||
import { ComfyApp } from "../../scripts/app";
|
||||
|
||||
export interface ComfyExtension {
|
||||
/**
|
||||
* The name of the extension
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Allows any initialisation, e.g. loading resources. Called after the canvas is created but before nodes are added
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
init?(app: ComfyApp): Promise<void>;
|
||||
/**
|
||||
* Allows any additonal setup, called after the application is fully set up and running
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
setup?(app: ComfyApp): Promise<void>;
|
||||
/**
|
||||
* Called before nodes are registered with the graph
|
||||
* @param defs The collection of node definitions, add custom ones or edit existing ones
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
addCustomNodeDefs?(defs: Record<string, ComfyObjectInfo>, app: ComfyApp): Promise<void>;
|
||||
/**
|
||||
* Allows the extension to add custom widgets
|
||||
* @param app The ComfyUI app instance
|
||||
* @returns An array of {[widget name]: widget data}
|
||||
*/
|
||||
getCustomWidgets?(
|
||||
app: ComfyApp
|
||||
): Promise<
|
||||
Record<string, (node, inputName, inputData, app) => { widget?: IWidget; minWidth?: number; minHeight?: number }>
|
||||
>;
|
||||
/**
|
||||
* Allows the extension to add additional handling to the node before it is registered with LGraph
|
||||
* @param nodeType The node class (not an instance)
|
||||
* @param nodeData The original node object info config object
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
beforeRegisterNodeDef?(nodeType: typeof LGraphNode, nodeData: ComfyObjectInfo, app: ComfyApp): Promise<void>;
|
||||
/**
|
||||
* Allows the extension to register additional nodes with LGraph after standard nodes are added
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
registerCustomNodes?(app: ComfyApp): Promise<void>;
|
||||
/**
|
||||
* Allows the extension to modify a node that has been reloaded onto the graph.
|
||||
* If you break something in the backend and want to patch workflows in the frontend
|
||||
* This is the place to do this
|
||||
* @param node The node that has been loaded
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
loadedGraphNode?(node: LGraphNode, app: ComfyApp);
|
||||
/**
|
||||
* Allows the extension to run code after the constructor of the node
|
||||
* @param node The node that has been created
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
nodeCreated?(node: LGraphNode, app: ComfyApp);
|
||||
/**
|
||||
* The name of the extension
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Allows any initialisation, e.g. loading resources. Called after the canvas is created but before nodes are added
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
init?(app: ComfyApp): Promise<void>;
|
||||
/**
|
||||
* Allows any additonal setup, called after the application is fully set up and running
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
setup?(app: ComfyApp): Promise<void>;
|
||||
/**
|
||||
* Called before nodes are registered with the graph
|
||||
* @param defs The collection of node definitions, add custom ones or edit existing ones
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
addCustomNodeDefs?(
|
||||
defs: Record<string, ComfyObjectInfo>,
|
||||
app: ComfyApp
|
||||
): Promise<void>;
|
||||
/**
|
||||
* Allows the extension to add custom widgets
|
||||
* @param app The ComfyUI app instance
|
||||
* @returns An array of {[widget name]: widget data}
|
||||
*/
|
||||
getCustomWidgets?(
|
||||
app: ComfyApp
|
||||
): Promise<
|
||||
Record<
|
||||
string,
|
||||
(
|
||||
node,
|
||||
inputName,
|
||||
inputData,
|
||||
app
|
||||
) => { widget?: IWidget; minWidth?: number; minHeight?: number }
|
||||
>
|
||||
>;
|
||||
/**
|
||||
* Allows the extension to add additional handling to the node before it is registered with LGraph
|
||||
* @param nodeType The node class (not an instance)
|
||||
* @param nodeData The original node object info config object
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
beforeRegisterNodeDef?(
|
||||
nodeType: typeof LGraphNode,
|
||||
nodeData: ComfyObjectInfo,
|
||||
app: ComfyApp
|
||||
): Promise<void>;
|
||||
/**
|
||||
* Allows the extension to register additional nodes with LGraph after standard nodes are added
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
registerCustomNodes?(app: ComfyApp): Promise<void>;
|
||||
/**
|
||||
* Allows the extension to modify a node that has been reloaded onto the graph.
|
||||
* If you break something in the backend and want to patch workflows in the frontend
|
||||
* This is the place to do this
|
||||
* @param node The node that has been loaded
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
loadedGraphNode?(node: LGraphNode, app: ComfyApp);
|
||||
/**
|
||||
* Allows the extension to run code after the constructor of the node
|
||||
* @param node The node that has been created
|
||||
* @param app The ComfyUI app instance
|
||||
*/
|
||||
nodeCreated?(node: LGraphNode, app: ComfyApp);
|
||||
}
|
||||
|
||||
export type ComfyObjectInfo = {
|
||||
name: string;
|
||||
display_name?: string;
|
||||
description?: string;
|
||||
category: string;
|
||||
input?: {
|
||||
required?: Record<string, ComfyObjectInfoConfig>;
|
||||
optional?: Record<string, ComfyObjectInfoConfig>;
|
||||
};
|
||||
output?: string[];
|
||||
output_name: string[];
|
||||
name: string;
|
||||
display_name?: string;
|
||||
description?: string;
|
||||
category: string;
|
||||
input?: {
|
||||
required?: Record<string, ComfyObjectInfoConfig>;
|
||||
optional?: Record<string, ComfyObjectInfoConfig>;
|
||||
};
|
||||
output?: string[];
|
||||
output_name: string[];
|
||||
};
|
||||
|
||||
export type ComfyObjectInfoConfig = [string | any[]] | [string | any[], any];
|
||||
|
||||
@@ -1,47 +1,56 @@
|
||||
import { z } from 'zod';
|
||||
import { fromZodError } from 'zod-validation-error';
|
||||
import { z } from "zod";
|
||||
import { fromZodError } from "zod-validation-error";
|
||||
|
||||
const zComfyLink = z.tuple([
|
||||
z.number(), // Link id
|
||||
z.number(), // Node id of source node
|
||||
z.number(), // Output slot# of source node
|
||||
z.number(), // Node id of destination node
|
||||
z.number(), // Input slot# of destination node
|
||||
z.string(), // Data type
|
||||
z.number(), // Link id
|
||||
z.number(), // Node id of source node
|
||||
z.number(), // Output slot# of source node
|
||||
z.number(), // Node id of destination node
|
||||
z.number(), // Input slot# of destination node
|
||||
z.string(), // Data type
|
||||
]);
|
||||
|
||||
const zNodeOutput = z.object({
|
||||
const zNodeOutput = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
type: z.string(),
|
||||
links: z.array(z.number()).nullable(),
|
||||
slot_index: z.number().optional(),
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const zNodeInput = z.object({
|
||||
const zNodeInput = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
type: z.string(),
|
||||
link: z.number().nullable(),
|
||||
slot_index: z.number().optional(),
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const zFlags = z.object({
|
||||
const zFlags = z
|
||||
.object({
|
||||
collapsed: z.boolean().optional(),
|
||||
pinned: z.boolean().optional(),
|
||||
allow_interaction: z.boolean().optional(),
|
||||
horizontal: z.boolean().optional(),
|
||||
skip_repeated_outputs: z.boolean().optional(),
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const zProperties = z.object({
|
||||
const zProperties = z
|
||||
.object({
|
||||
["Node name for S&R"]: z.string().optional(),
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const zVector2 = z.union([
|
||||
z.object({ 0: z.number(), 1: z.number() }),
|
||||
z.tuple([z.number(), z.number()]),
|
||||
z.object({ 0: z.number(), 1: z.number() }),
|
||||
z.tuple([z.number(), z.number()]),
|
||||
]);
|
||||
|
||||
const zComfyNode = z.object({
|
||||
const zComfyNode = z
|
||||
.object({
|
||||
id: z.number(),
|
||||
type: z.string(),
|
||||
pos: z.tuple([z.number(), z.number()]),
|
||||
@@ -52,20 +61,24 @@ const zComfyNode = z.object({
|
||||
inputs: z.array(zNodeInput).optional(),
|
||||
outputs: z.array(zNodeOutput).optional(),
|
||||
properties: zProperties,
|
||||
widgets_values: z.array(z.any()).optional(), // This could contain mixed types
|
||||
widgets_values: z.array(z.any()).optional(), // This could contain mixed types
|
||||
color: z.string().optional(),
|
||||
bgcolor: z.string().optional(),
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const zGroup = z.object({
|
||||
const zGroup = z
|
||||
.object({
|
||||
title: z.string(),
|
||||
bounding: z.tuple([z.number(), z.number(), z.number(), z.number()]),
|
||||
color: z.string(),
|
||||
font_size: z.number(),
|
||||
locked: z.boolean().optional(),
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const zInfo = z.object({
|
||||
const zInfo = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
author: z.string(),
|
||||
description: z.string(),
|
||||
@@ -73,24 +86,32 @@ const zInfo = z.object({
|
||||
created: z.string(),
|
||||
modified: z.string(),
|
||||
software: z.string(),
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const zDS = z.object({
|
||||
const zDS = z
|
||||
.object({
|
||||
scale: z.number(),
|
||||
offset: zVector2,
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const zConfig = z.object({
|
||||
const zConfig = z
|
||||
.object({
|
||||
links_ontop: z.boolean().optional(),
|
||||
align_to_grid: z.boolean().optional(),
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const zExtra = z.object({
|
||||
const zExtra = z
|
||||
.object({
|
||||
ds: zDS.optional(),
|
||||
info: zInfo.optional(),
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
export const zComfyWorkflow = z.object({
|
||||
export const zComfyWorkflow = z
|
||||
.object({
|
||||
last_node_id: z.number(),
|
||||
last_link_id: z.number(),
|
||||
nodes: z.array(zComfyNode),
|
||||
@@ -99,7 +120,8 @@ export const zComfyWorkflow = z.object({
|
||||
config: zConfig.optional().nullable(),
|
||||
extra: zExtra.optional().nullable(),
|
||||
version: z.number(),
|
||||
}).passthrough();
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
export type NodeInput = z.infer<typeof zNodeInput>;
|
||||
export type NodeOutput = z.infer<typeof zNodeOutput>;
|
||||
@@ -107,15 +129,14 @@ export type ComfyLink = z.infer<typeof zComfyLink>;
|
||||
export type ComfyNode = z.infer<typeof zComfyNode>;
|
||||
export type ComfyWorkflow = z.infer<typeof zComfyWorkflow>;
|
||||
|
||||
|
||||
export async function parseComfyWorkflow(data: string): Promise<ComfyWorkflow> {
|
||||
// Validate
|
||||
const result = await zComfyWorkflow.safeParseAsync(JSON.parse(data));
|
||||
if (!result.success) {
|
||||
// TODO: Pretty print the error on UI modal.
|
||||
const error = fromZodError(result.error);
|
||||
alert(`Invalid workflow against zod schema:\n${error}`);
|
||||
throw error;
|
||||
}
|
||||
return result.data;
|
||||
// Validate
|
||||
const result = await zComfyWorkflow.safeParseAsync(JSON.parse(data));
|
||||
if (!result.success) {
|
||||
// TODO: Pretty print the error on UI modal.
|
||||
const error = fromZodError(result.error);
|
||||
alert(`Invalid workflow against zod schema:\n${error}`);
|
||||
throw error;
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
|
||||
2767
src/types/litegraph.d.ts
vendored
2767
src/types/litegraph.d.ts
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user