n8n-nodes-hjhcomfyui
Version:
n8n node to integrate with ComfyUI stable diffusion workflows
203 lines • 20 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Hjhcomfyuicheck = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const n8n_workflow_2 = require("n8n-workflow");
const hjh_node_image_1 = require("hjh-node-image");
class Hjhcomfyuicheck {
constructor() {
this.description = {
displayName: 'HjhComfyUICheck',
name: 'hjhcomfyuicheck',
icon: 'file:hjhcomfyuicheck.svg',
group: ['transform'],
version: 1,
description: 'Execute HjhComfyUICheck workflows',
defaults: {
name: 'HjhComfyUICheck',
},
credentials: [
{
name: 'hjhComfyUIApi',
required: true,
},
],
inputs: ['main'],
outputs: ['main'],
properties: [
{
displayName: 'Use Hjh Services',
name: 'useHjhServices',
type: 'boolean',
default: true,
description: 'Whether to use Hjh services in the workflow',
},
{
displayName: 'Hjh Services',
name: 'services',
type: 'string',
typeOptions: {
rows: 10,
},
default: '',
description: 'The Hjh services in JSON format',
},
{
displayName: 'Hjh Workflow JSON',
name: 'workflow',
type: 'string',
typeOptions: {
rows: 10,
},
default: '',
required: true,
description: 'The HjhComfyUICheck workflow in JSON format',
},
{
displayName: 'Timeout',
name: 'timeout',
type: 'number',
default: 30,
description: 'Maximum time in minutes to wait for workflow completion',
},
],
};
}
async execute() {
var _a, _b;
const credentials = await this.getCredentials('hjhComfyUIApi');
const useHjhServices = this.getNodeParameter('useHjhServices', 0);
const services = this.getNodeParameter('services', 0);
const workflow = this.getNodeParameter('workflow', 0);
const timeout = this.getNodeParameter('timeout', 0);
let apiUrl = "";
let apiKey = "";
if (useHjhServices) {
if (services) {
let services1 = JSON.parse(services);
apiUrl = services1.comfyui;
}
else {
apiUrl = credentials.apiUrl;
apiKey = credentials.apiKey;
}
}
else {
apiUrl = credentials.apiUrl;
apiKey = credentials.apiKey;
}
let url = apiUrl;
console.log('[HjhComfyUICheck] Executing with API URL:', apiUrl);
const headers = {
'Content-Type': 'application/json',
};
if (apiKey) {
console.log('[HjhComfyUICheck] Using API key authentication');
headers['Authorization'] = `Bearer ${apiKey}`;
}
try {
console.log('[HjhComfyUICheck] Checking API connection...');
url = `${apiUrl}/system_stats`;
await this.helpers.request({
method: 'GET',
url: `${apiUrl}/system_stats`,
headers,
json: true,
});
console.log('[HjhComfyUICheck] Queueing prompt...');
url = `${apiUrl}/prompt`;
const response = await this.helpers.request({
method: 'POST',
url: `${apiUrl}/prompt`,
headers,
body: {
prompt: JSON.parse(workflow),
},
json: true,
});
if (!response.prompt_id) {
throw new n8n_workflow_2.NodeApiError(this.getNode(), { message: 'Failed to get prompt ID from HjhComfyUICheck' });
}
const promptId = response.prompt_id;
console.log('[HjhComfyUICheck] Prompt queued with ID:', promptId);
let attempts = 0;
const maxAttempts = 60 * timeout;
await new Promise(resolve => setTimeout(resolve, 5000));
while (attempts < maxAttempts) {
console.log(`[HjhComfyUICheck] Checking execution status (attempt ${attempts + 1}/${maxAttempts})...`);
await new Promise(resolve => setTimeout(resolve, 1000));
attempts++;
const history = await this.helpers.request({
method: 'GET',
url: `${apiUrl}/history/${promptId}`,
headers,
json: true,
});
const promptResult = history[promptId];
if (!promptResult) {
console.log('[HjhComfyUICheck] Prompt not found in history');
continue;
}
if (promptResult.status === undefined) {
console.log('[HjhComfyUICheck] Execution status not found');
continue;
}
if ((_a = promptResult.status) === null || _a === void 0 ? void 0 : _a.completed) {
console.log('[HjhComfyUICheck] Execution completed');
if (((_b = promptResult.status) === null || _b === void 0 ? void 0 : _b.status_str) === 'error') {
throw new n8n_workflow_2.NodeApiError(this.getNode(), { message: '[HjhComfyUICheck] Workflow execution failed' });
}
if (!promptResult.outputs) {
throw new n8n_workflow_2.NodeApiError(this.getNode(), { message: '[HjhComfyUICheck] No outputs found in workflow result' });
}
console.log(promptResult);
let files;
files = Object.values(promptResult.outputs)
.flatMap((nodeOutput) => nodeOutput.images || [])
.filter((image) => image.type === 'output' || image.type === 'temp')
.map((file) => {
console.log(`[HjhComfyUICheck] Downloading ${file.type} image:`, file.filename);
console.log(file);
return file.subfolder + "\\" + file.filename;
});
console.log(files);
let json = '{"6": {"_meta": {"title": "LoRA_1"}, "inputs": {"clip": ["96:2", 0], "model": ["96:0", 0], "lora_name": "Ly_GoodHands_beta2.safetensors", "strength_clip": 1.3, "strength_model": 1.3}, "class_type": "LoraLoader"}, "7": {"_meta": {"title": "LoRA_2"}, "inputs": {"clip": ["6", 1], "model": ["6", 0], "lora_name": "ControlLoRA\\\\openpose_rank128_v11p_sd15_fp16.safetensors", "strength_clip": 1, "strength_model": 1}, "class_type": "LoraLoader"}, "8": {"_meta": {"title": "LoRA_3"}, "inputs": {"clip": ["7", 1], "model": ["7", 0], "lora_name": "IP-Adapter\\\\ip-adapter-faceid_sd15_lora.safetensors", "strength_clip": 0, "strength_model": 0.2}, "class_type": "LoraLoader"}, "9": {"_meta": {"title": "LoRA_4"}, "inputs": {"clip": ["8", 1], "model": ["8", 0], "lora_name": "IP-Adapter\\\\ip-adapter-faceid-plusv2_sd15_lora.safetensors", "strength_clip": 0, "strength_model": 0.2}, "class_type": "LoraLoader"}, "10": {"_meta": {"title": "LoRA_5"}, "inputs": {"clip": ["9", 1], "model": ["9", 0], "lora_name": "Moxin_10.safetensors", "strength_clip": 0, "strength_model": 0}, "class_type": "LoraLoader"}, "11": {"_meta": {"title": "LoRA_6"}, "inputs": {"clip": ["10", 1], "model": ["10", 0], "lora_name": "SongPainting_v1.0.safetensors", "strength_clip": 0, "strength_model": 0.1}, "class_type": "LoraLoader"}, "59": {"_meta": {"title": "FreeU_V2"}, "inputs": {"b1": 1.41, "b2": 1.6, "s1": 0.9, "s2": 0.2, "model": ["79:2", 0]}, "class_type": "FreeU_V2"}, "60": {"_meta": {"title": "HyperTile"}, "inputs": {"model": ["59", 0], "max_depth": 0, "swap_size": 2, "tile_size": 576, "scale_depth": false}, "class_type": "HyperTile"}, "119": {"_meta": {"title": "HJH Save Image Webp"}, "inputs": {"EXIF": false, "images": ["117:6", 0], "quality": 85, "isLossless": false, "print_size": 0, "thumb_size": 0, "filename_prefix": "//NAS65A682/Web/images/openapi_img/tmp/2025/06/18/0_0_67"}, "class_type": "SaveImageWebp"}, "216": {"_meta": {"title": "Hyper-SD"}, "inputs": {"model": ["60", 0], "lora_name": "Hyper-SD\\\\Hyper-SD15-4steps-lora.safetensors", "strength_model": 0.5}, "class_type": "LoraLoaderModelOnly"}, "5:0": {"_meta": {"title": "CKPT_1"}, "inputs": {"ckpt_name": "De2Aa1Ao1Dr1.safetensors"}, "class_type": "CheckpointLoaderSimple"}, "5:1": {"_meta": {"title": "CKPT_2"}, "inputs": {"ckpt_name": "AWPainting_v1.2.safetensors"}, "class_type": "CheckpointLoaderSimple"}, "5:2": {"_meta": {"title": "CKPT_3"}, "inputs": {"ckpt_name": "AWPortrait_v1.2.safetensors"}, "class_type": "CheckpointLoaderSimple"}, "5:3": {"_meta": {"title": "Load VAE"}, "inputs": {"vae_name": "vae-ft-mse-840000-ema-pruned.ckpt"}, "class_type": "VAELoader"}, "20:0": {"_meta": {"title": "IP"}, "inputs": {"ipadapter_file": "ip-adapter_sd15.safetensors"}, "class_type": "IPAdapterModelLoader"}, "20:1": {"_meta": {"title": "Plus"}, "inputs": {"ipadapter_file": "ip-adapter-plus_sd15.safetensors"}, "class_type": "IPAdapterModelLoader"}, "20:2": {"_meta": {"title": "FaceID"}, "inputs": {"ipadapter_file": "ip-adapter-faceid-plusv2_sd15.bin"}, "class_type": "IPAdapterModelLoader"}, "20:3": {"_meta": {"title": "Portrait"}, "inputs": {"ipadapter_file": "ip-adapter-faceid-portrait-v11_sd15.bin"}, "class_type": "IPAdapterModelLoader"}, "20:4": {"_meta": {"title": "CLIP Vision"}, "inputs": {"clip_name": "image_encoder_model_sd15.safetensors"}, "class_type": "CLIPVisionLoader"}, "20:5": {"_meta": {"title": "InsightFace"}, "inputs": {"provider": "CUDA"}, "class_type": "IPAdapterInsightFaceLoader"}, "24:0": {"_meta": {"title": "DWPose Estimator"}, "inputs": {"image": ["75:0", 0], "resolution": ["75:2", 0], "detect_body": "enable", "detect_face": "enable", "detect_hand": "enable", "bbox_detector": "yolox_l.onnx", "pose_estimator": "dw-ll_ucoco_384.onnx"}, "class_type": "DWPreprocessor"}, "24:1": {"_meta": {"title": "Load ControlNet Model"}, "inputs": {"control_net_name": "fp16\\\\control_v11p_sd15_openpose_fp16.safetensors"}, "class_type": "ControlNetLoader"}, "24:2": {"_meta": {"title": "Apply ControlNet"}, "inputs": {"image": ["24:0", 0], "strength": 1.3, "control_net": ["24:1", 0], "conditioning": ["109:6", 0]}, "class_type": "ControlNetApply"}, "28:0": {"_meta": {"title": "TEEDPreprocessor"}, "inputs": {"image": ["75:0", 0], "resolution": ["75:2", 0], "safe_steps": 2}, "class_type": "TEEDPreprocessor"}, "28:1": {"_meta": {"title": "Load ControlNet Model"}, "inputs": {"control_net_name": "fp16\\\\control_v11p_sd15s2_lineart_anime_fp16.safetensors"}, "class_type": "ControlNetLoader"}, "28:2": {"_meta": {"title": "Apply ControlNet"}, "inputs": {"image": ["28:0", 0], "strength": 0.3, "control_net": ["28:1", 0], "conditioning": ["24:2", 0]}, "class_type": "ControlNetApply"}, "65:0": {"_meta": {"title": "ModelSamplingDiscrete"}, "inputs": {"zsnr": false, "model": ["199:1", 0], "sampling": "lcm"}, "class_type": "ModelSamplingDiscrete"}, "65:1": {"_meta": {"title": "Load LoRA"}, "inputs": {"clip": ["11", 1], "model": ["65:0", 0], "lora_name": "lcm\\\\lcm_lora_sd15.safetensors", "strength_clip": 1, "strength_model": 1}, "class_type": "LoraLoader"}, "75:0": {"_meta": {"title": "HJH Load Image Advance"}, "inputs": {"image": "//NAS65A682/Web/images/test/user_img/orig/2024/08/09/d873dc55d9ec81bce6c07642ec74e22b_test_AA23GG2.jpg", "upload": null, "image_path": ""}, "class_type": "LoadImageAdv"}, "75:1": {"_meta": {"title": "HJH Get Image Size"}, "inputs": {"image": ["75:0", 0]}, "class_type": "GetImageSize"}, "75:2": {"_meta": {"title": "Pixel Perfect Resolution"}, "inputs": {"resize_mode": "Crop and Resize", "original_image": ["75:0", 0], "image_gen_width": ["75:1", 0], "image_gen_height": ["75:1", 1]}, "class_type": "PixelPerfectResolution"}, "75:3": {"_meta": {"title": "VAE Encode"}, "inputs": {"vae": ["5:3", 0], "pixels": ["75:0", 0]}, "class_type": "VAEEncode"}, "75:4": {"_meta": {"title": "Empty Latent Image"}, "inputs": {"width": ["75:1", 0], "height": ["75:1", 1], "batch_size": 1}, "class_type": "EmptyLatentImage"}, "75:5": {"_meta": {"title": "ImageMultiply"}, "inputs": {"samples": ["75:3", 0], "multiplier": 0.5}, "class_type": "LatentMultiply"}, "75:6": {"_meta": {"title": "EmptyMultiply"}, "inputs": {"samples": ["75:4", 0], "multiplier": 0.5}, "class_type": "LatentMultiply"}, "75:7": {"_meta": {"title": "LatentAdd"}, "inputs": {"samples1": ["75:6", 0], "samples2": ["75:5", 0]}, "class_type": "LatentAdd"}, "75:8": {"_meta": {"title": "Repeat Latent Batch"}, "inputs": {"amount": 4, "samples": ["75:7", 0]}, "class_type": "RepeatLatentBatch"}, "79:0": {"_meta": {"title": "IPAdapter Load Embeds"}, "inputs": {"embeds": "embeds\\\\RococoPlus4_v240420.ipadpt"}, "class_type": "IPAdapterLoadEmbeds"}, "79:1": {"_meta": {"title": "IPAdapter Combine Embeds"}, "inputs": {"embed1": ["79:0", 0], "method": "concat"}, "class_type": "IPAdapterCombineEmbeds"}, "79:2": {"_meta": {"title": "IPAdapter Embeds"}, "inputs": {"model": ["11", 0], "end_at": 1, "weight": 1, "start_at": 0, "ipadapter": ["20:1", 0], "pos_embed": ["79:1", 0], "clip_vision": ["20:4", 0], "weight_type": "style transfer", "embeds_scaling": "K+V"}, "class_type": "IPAdapterEmbeds"}, "96:0": {"_meta": {"title": "ModelMergeSimple"}, "inputs": {"ratio": 1, "model1": ["5:0", 0], "model2": ["5:1", 0]}, "class_type": "ModelMergeSimple"}, "96:1": {"_meta": {"title": "CLIPMergeSimple"}, "inputs": {"clip1": ["5:0", 1], "clip2": ["5:1", 1], "ratio": 1}, "class_type": "CLIPMergeSimple"}, "96:2": {"_meta": {"title": "CLIP Set Last Layer"}, "inputs": {"clip": ["96:1", 0], "stop_at_clip_layer": -1}, "class_type": "CLIPSetLastLayer"}, "101:1": {"_meta": {"title": "Primary++"}, "inputs": {"clip": ["11", 1], "text": "23-years-old (female:1.6), (Rococo art, Franois Gérard:1.3), ", "width": 1024, "ascore": 6, "crop_h": 0, "crop_w": 0, "height": 1024, "parser": "comfy++", "text_g": "", "text_l": "", "smZ_steps": 1, "with_SDXL": false, "target_width": 1024, "target_height": 1024, "mean_normalization": true, "multi_conditioning": true, "use_old_emphasis_implementation": false}, "class_type": "smZ CLIPTextEncode"}, "101:2": {"_meta": {"title": "Secondary++"}, "inputs": {"clip": ["11", 1], "text": "(Well-dressed Royal:1.5) nobility (Oil painting), (gorgeous) authority but Childish, Masterpiece, Extreme details, Best quality, 8k Resolution", "width": 1024, "ascore": 6, "crop_h": 0, "crop_w": 0, "height": 1024, "parser": "comfy++", "text_g": "", "text_l": "", "smZ_steps": 1, "with_SDXL": false, "target_width": 1024, "target_height": 1024, "mean_normalization": true, "multi_conditioning": true, "use_old_emphasis_implementation": false}, "class_type": "smZ CLIPTextEncode"}, "101:3": {"_meta": {"title": "Negative"}, "inputs": {"clip": ["11", 1], "text": "nsfw, phoptorealistic, (dirty face:1.3), error, embedding:easynegative"}, "class_type": "CLIPTextEncode"}, "109:2": {"_meta": {"title": "PriTime"}, "inputs": {"end": 1, "start": 0, "conditioning": ["101:1", 0]}, "class_type": "ConditioningSetTimestepRange"}, "109:3": {"_meta": {"title": "SecTime"}, "inputs": {"end": 1, "start": 0.2, "conditioning": ["101:2", 0]}, "class_type": "ConditioningSetTimestepRange"}, "109:4": {"_meta": {"title": "Average"}, "inputs": {"conditioning_to": ["101:1", 0], "conditioning_from": ["101:2", 0], "conditioning_to_strength": 0.5}, "class_type": "ConditioningAverage"}, "109:5": {"_meta": {"title": "Concat"}, "inputs": {"conditioning_to": ["101:1", 0], "conditioning_from": ["101:2", 0]}, "class_type": "ConditioningConcat"}, "109:6": {"_meta": {"title": "Combine"}, "inputs": {"conditioning_1": ["109:2", 0], "conditioning_2": ["109:3", 0]}, "class_type": "ConditioningCombine"}, "117:3": {"_meta": {"title": "KSampler_1"}, "inputs": {"cfg": 1, "seed": "340274885982195", "model": ["216", 0], "steps": 4, "denoise": 0.8, "negative": ["101:3", 0], "positive": ["28:2", 0], "scheduler": "sgm_uniform", "latent_image": ["75:8", 0], "sampler_name": "ddim"}, "class_type": "KSampler"}, "117:4": {"_meta": {"title": "VAE_1"}, "inputs": {"vae": ["5:3", 0], "samples": ["117:3", 0]}, "class_type": "VAEDecode"}, "117:5": {"_meta": {"title": "KSampler_2"}, "inputs": {"cfg": 1.6, "seed": "340274885982195", "model": ["65:1", 0], "steps": 4, "denoise": 0.36, "negative": ["101:3", 0], "positive": ["28:2", 0], "scheduler": "karras", "latent_image": ["117:3", 0], "sampler_name": "lcm"}, "class_type": "KSampler"}, "117:6": {"_meta": {"title": "VAE_2"}, "inputs": {"vae": ["5:3", 0], "samples": ["117:5", 0]}, "class_type": "VAEDecode"}, "199:0": {"_meta": {"title": "FaceID Portrait"}, "inputs": {"image": ["75:0", 0], "model": ["60", 0], "end_at": 1, "weight": 1, "start_at": 0, "ipadapter": ["20:3", 0], "clip_vision": ["20:4", 0], "insightface": ["20:5", 0], "weight_type": "linear", "combine_embeds": "concat", "embeds_scaling": "K+V", "weight_faceidv2": 0.5}, "class_type": "IPAdapterFaceID"}, "199:1": {"_meta": {"title": "FaceID Plus"}, "inputs": {"image": ["75:0", 0], "model": ["199:0", 0], "end_at": 1, "weight": 0.5, "start_at": 0, "ipadapter": ["20:2", 0], "clip_vision": ["20:4", 0], "insightface": ["20:5", 0], "weight_type": "linear", "combine_embeds": "concat", "embeds_scaling": "K+V", "weight_faceidv2": 1}, "class_type": "IPAdapterFaceID"}}';
json = (0, hjh_node_image_1.replaceJson)(json, 'filename', files);
let responseData = {
code: 200,
message: 'ok',
description: 'ok',
files: files,
promptResult: promptResult,
promptId: promptId,
'workflow': json
};
console.log('[HjhComfyUICheck] All images downloaded successfully');
return [this.helpers.returnJsonArray(responseData)];
}
}
throw new n8n_workflow_2.NodeApiError(this.getNode(), { message: `Execution timeout after ${timeout} minutes` });
}
catch (error) {
console.error('[HjhComfyUICheck] Execution error:', error);
this.logger.error('[HjhComfyUICheck] Execution error:', error);
if (!this.continueOnFail()) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), {
message: `HjhComfyUICheck API Error: ${error.message} ${url} ${apiUrl} ${apiKey} ` + error.toString(),
description: `HjhComfyUICheck API Error: ${error.message} ${url} ${apiUrl} ${apiKey} ` + error.toString()
}, {
message: `HjhComfyUICheck API Error: ${error.message} ${url} ${apiUrl} ${apiKey} ` + error.toString(),
description: `HjhComfyUICheck API Error: ${error.message} ${url} ${apiUrl} ${apiKey} ` + error.toString()
});
}
let errorItems = {
code: 500,
message: error.message,
description: `HjhComfyUICheck API Error: ${error.message} ${url} ${apiUrl} ${apiKey} ${error.toString()} ` + error.stack,
};
return [this.helpers.returnJsonArray(errorItems)];
}
}
}
exports.Hjhcomfyuicheck = Hjhcomfyuicheck;
//# sourceMappingURL=Hjhcomfyuicheck.node.js.map