n8n-nodes-piapi
Version:
Community n8n nodes for PiAPI - integrate generative AI capabilities (image, video, audio, 3D) into your workflows
426 lines • 19 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.KlingTryOn = void 0;
const GenericFunctions_1 = require("../shared/GenericFunctions");
class KlingTryOn {
constructor() {
this.description = {
displayName: 'PiAPI Kling Virtual Try On',
name: 'klingTryOn',
icon: 'file:../piapi.svg',
group: ['transform'],
version: 1,
description: 'Generate virtual clothing try-on images using PiAPI Kling ($0.07 per image)',
defaults: {
name: 'Kling Virtual Try On',
},
inputs: ["main"],
outputs: ["main"],
credentials: [
{
name: 'piAPIApi',
required: true,
},
],
properties: [
{
displayName: 'Model Image Source',
name: 'modelImageSource',
type: 'options',
options: [
{
name: 'URL',
value: 'url',
description: 'Load model image from URL',
},
{
name: 'Binary Data',
value: 'binaryData',
description: 'Use model image from binary field',
},
],
default: 'url',
description: 'Source of the model (person) image',
},
{
displayName: 'Model Image URL',
name: 'modelImageUrl',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
modelImageSource: ['url'],
},
},
description: 'URL of the model (person) image',
},
{
displayName: 'Model Binary Property',
name: 'modelBinaryPropertyName',
type: 'string',
default: 'model',
required: true,
displayOptions: {
show: {
modelImageSource: ['binaryData'],
},
},
description: 'Name of the binary property containing the model image',
},
{
displayName: 'Garment Type',
name: 'garmentType',
type: 'options',
options: [
{
name: 'Full Dress',
value: 'dress',
description: 'Full-body garment',
},
{
name: 'Upper and Lower Separately',
value: 'upperLower',
description: 'Upper and lower body garments separately',
},
],
default: 'dress',
description: 'Type of garment to try on',
},
{
displayName: 'Dress Image Source',
name: 'dressImageSource',
type: 'options',
options: [
{
name: 'URL',
value: 'url',
description: 'Load dress image from URL',
},
{
name: 'Binary Data',
value: 'binaryData',
description: 'Use dress image from binary field',
},
],
default: 'url',
displayOptions: {
show: {
garmentType: ['dress'],
},
},
description: 'Source of the dress image',
},
{
displayName: 'Dress Image URL',
name: 'dressImageUrl',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
garmentType: ['dress'],
dressImageSource: ['url'],
},
},
description: 'URL of the full-body garment image',
},
{
displayName: 'Dress Binary Property',
name: 'dressBinaryPropertyName',
type: 'string',
default: 'dress',
required: true,
displayOptions: {
show: {
garmentType: ['dress'],
dressImageSource: ['binaryData'],
},
},
description: 'Name of the binary property containing the dress image',
},
{
displayName: 'Upper Garment Image Source',
name: 'upperImageSource',
type: 'options',
options: [
{
name: 'URL',
value: 'url',
description: 'Load upper garment image from URL',
},
{
name: 'Binary Data',
value: 'binaryData',
description: 'Use upper garment image from binary field',
},
],
default: 'url',
displayOptions: {
show: {
garmentType: ['upperLower'],
},
},
description: 'Source of the upper garment image',
},
{
displayName: 'Upper Garment Image URL',
name: 'upperImageUrl',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
garmentType: ['upperLower'],
upperImageSource: ['url'],
},
},
description: 'URL of the upper-body garment image',
},
{
displayName: 'Upper Garment Binary Property',
name: 'upperBinaryPropertyName',
type: 'string',
default: 'upper',
required: true,
displayOptions: {
show: {
garmentType: ['upperLower'],
upperImageSource: ['binaryData'],
},
},
description: 'Name of the binary property containing the upper garment image',
},
{
displayName: 'Lower Garment Image Source',
name: 'lowerImageSource',
type: 'options',
options: [
{
name: 'URL',
value: 'url',
description: 'Load lower garment image from URL',
},
{
name: 'Binary Data',
value: 'binaryData',
description: 'Use lower garment image from binary field',
},
],
default: 'url',
displayOptions: {
show: {
garmentType: ['upperLower'],
},
},
description: 'Source of the lower garment image',
},
{
displayName: 'Lower Garment Image URL',
name: 'lowerImageUrl',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
garmentType: ['upperLower'],
lowerImageSource: ['url'],
},
},
description: 'URL of the lower-body garment image',
},
{
displayName: 'Lower Garment Binary Property',
name: 'lowerBinaryPropertyName',
type: 'string',
default: 'lower',
required: true,
displayOptions: {
show: {
garmentType: ['upperLower'],
lowerImageSource: ['binaryData'],
},
},
description: 'Name of the binary property containing the lower garment image',
},
{
displayName: 'Batch Size',
name: 'batchSize',
type: 'number',
typeOptions: {
minValue: 1,
maxValue: 4,
},
default: 1,
description: 'Number of variations to generate (1-4)',
},
{
displayName: 'Wait for Completion',
name: 'waitForCompletion',
type: 'boolean',
default: false,
description: 'Whether to wait for the task to complete before returning',
},
],
};
}
async execute() {
var _a, _b, _c, _d;
const items = this.getInputData();
const returnData = [];
for (let i = 0; i < items.length; i++) {
try {
const modelImageSource = this.getNodeParameter('modelImageSource', i);
const garmentType = this.getNodeParameter('garmentType', i);
const batchSize = this.getNodeParameter('batchSize', i, 1);
const waitForCompletion = this.getNodeParameter('waitForCompletion', i, false);
let modelImageUrl = '';
let dressImageUrl = '';
let upperImageUrl = '';
let lowerImageUrl = '';
if (modelImageSource === 'url') {
modelImageUrl = this.getNodeParameter('modelImageUrl', i);
try {
new URL(modelImageUrl);
}
catch (error) {
throw new Error(`Invalid model image URL: ${error.message}`);
}
}
else if (modelImageSource === 'binaryData') {
const modelBinaryPropertyName = this.getNodeParameter('modelBinaryPropertyName', i);
const binaryItem = (_a = items[i].binary) === null || _a === void 0 ? void 0 : _a[modelBinaryPropertyName];
if (!binaryItem) {
throw new Error(`No binary data found in property ${modelBinaryPropertyName}`);
}
const binaryData = await this.helpers.getBinaryDataBuffer(i, modelBinaryPropertyName);
if (!binaryData) {
throw new Error(`No binary data found in property ${modelBinaryPropertyName}`);
}
const binaryMimeType = binaryItem.mimeType || 'image/png';
modelImageUrl = `data:${binaryMimeType};base64,${binaryData.toString('base64')}`;
}
if (garmentType === 'dress') {
const dressImageSource = this.getNodeParameter('dressImageSource', i);
if (dressImageSource === 'url') {
dressImageUrl = this.getNodeParameter('dressImageUrl', i);
try {
new URL(dressImageUrl);
}
catch (error) {
throw new Error(`Invalid dress image URL: ${error.message}`);
}
}
else if (dressImageSource === 'binaryData') {
const dressBinaryPropertyName = this.getNodeParameter('dressBinaryPropertyName', i);
const binaryItem = (_b = items[i].binary) === null || _b === void 0 ? void 0 : _b[dressBinaryPropertyName];
if (!binaryItem) {
throw new Error(`No binary data found in property ${dressBinaryPropertyName}`);
}
const binaryData = await this.helpers.getBinaryDataBuffer(i, dressBinaryPropertyName);
if (!binaryData) {
throw new Error(`No binary data found in property ${dressBinaryPropertyName}`);
}
const binaryMimeType = binaryItem.mimeType || 'image/png';
dressImageUrl = `data:${binaryMimeType};base64,${binaryData.toString('base64')}`;
}
}
else if (garmentType === 'upperLower') {
const upperImageSource = this.getNodeParameter('upperImageSource', i);
if (upperImageSource === 'url') {
upperImageUrl = this.getNodeParameter('upperImageUrl', i);
try {
new URL(upperImageUrl);
}
catch (error) {
throw new Error(`Invalid upper garment image URL: ${error.message}`);
}
}
else if (upperImageSource === 'binaryData') {
const upperBinaryPropertyName = this.getNodeParameter('upperBinaryPropertyName', i);
const binaryItem = (_c = items[i].binary) === null || _c === void 0 ? void 0 : _c[upperBinaryPropertyName];
if (!binaryItem) {
throw new Error(`No binary data found in property ${upperBinaryPropertyName}`);
}
const binaryData = await this.helpers.getBinaryDataBuffer(i, upperBinaryPropertyName);
if (!binaryData) {
throw new Error(`No binary data found in property ${upperBinaryPropertyName}`);
}
const binaryMimeType = binaryItem.mimeType || 'image/png';
upperImageUrl = `data:${binaryMimeType};base64,${binaryData.toString('base64')}`;
}
const lowerImageSource = this.getNodeParameter('lowerImageSource', i);
if (lowerImageSource === 'url') {
lowerImageUrl = this.getNodeParameter('lowerImageUrl', i);
try {
new URL(lowerImageUrl);
}
catch (error) {
throw new Error(`Invalid lower garment image URL: ${error.message}`);
}
}
else if (lowerImageSource === 'binaryData') {
const lowerBinaryPropertyName = this.getNodeParameter('lowerBinaryPropertyName', i);
const binaryItem = (_d = items[i].binary) === null || _d === void 0 ? void 0 : _d[lowerBinaryPropertyName];
if (!binaryItem) {
throw new Error(`No binary data found in property ${lowerBinaryPropertyName}`);
}
const binaryData = await this.helpers.getBinaryDataBuffer(i, lowerBinaryPropertyName);
if (!binaryData) {
throw new Error(`No binary data found in property ${lowerBinaryPropertyName}`);
}
const binaryMimeType = binaryItem.mimeType || 'image/png';
lowerImageUrl = `data:${binaryMimeType};base64,${binaryData.toString('base64')}`;
}
}
const body = {
model: 'kling',
task_type: 'ai_try_on',
input: {
model_input: modelImageUrl,
batch_size: batchSize,
},
config: {
webhook_config: {
endpoint: '',
secret: '',
},
},
};
if (garmentType === 'dress') {
body.input.dress_input = dressImageUrl;
}
else if (garmentType === 'upperLower') {
body.input.upper_input = upperImageUrl;
body.input.lower_input = lowerImageUrl;
}
const response = await GenericFunctions_1.piApiRequest.call(this, 'POST', '/api/v1/task', body);
if (response.code !== 200) {
throw new Error(`API Error: ${response.message}`);
}
const taskId = response.data.task_id;
let taskData = response.data;
if (waitForCompletion) {
taskData = await GenericFunctions_1.waitForTaskCompletion.call(this, taskId);
}
returnData.push({
json: taskData,
});
}
catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: {
error: error.message,
},
});
continue;
}
throw error;
}
}
return [returnData];
}
}
exports.KlingTryOn = KlingTryOn;
//# sourceMappingURL=KlingTryOn.node.js.map
;