Format all code / Add pre-commit format hook (#81)

* Add format-guard

* Format code
This commit is contained in:
Chenlei Hu
2024-07-02 13:22:37 -04:00
committed by GitHub
parent 4fb7fa9db1
commit acdaa6a594
62 changed files with 28225 additions and 25406 deletions

View File

@@ -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`

View File

@@ -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
View File

@@ -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];

View File

@@ -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

File diff suppressed because it is too large Load Diff