UNPKG

n8n-nodes-piapi

Version:

Community n8n nodes for PiAPI - integrate generative AI capabilities (image, video, audio, 3D) into your workflows

426 lines 17.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PiAPIMidjourney = void 0; const n8n_workflow_1 = require("n8n-workflow"); const GenericFunctions_1 = require("../shared/GenericFunctions"); class PiAPIMidjourney { constructor() { this.description = { displayName: 'PiAPI Midjourney', name: 'piAPIMidjourney', icon: 'file:../piapi.svg', group: ['transform'], version: 1, description: 'Generate and manipulate images using PiAPI Midjourney', defaults: { name: 'Midjourney', }, inputs: ["main"], outputs: ["main"], credentials: [ { name: 'piAPIApi', required: true, }, ], properties: [ { displayName: 'Operation', name: 'operation', type: 'options', options: [ { name: 'Imagine', value: 'imagine', description: 'Generate 4 images from a text prompt', }, { name: 'Upscale', value: 'upscale', description: 'Upscale a selected image from a previous Imagine result', }, { name: 'Describe', value: 'describe', description: 'Generate prompt suggestions based on an image', }, ], default: 'imagine', description: 'Operation to perform', }, { displayName: 'Prompt', name: 'prompt', type: 'string', typeOptions: { rows: 4, }, default: '', required: true, displayOptions: { show: { operation: ['imagine'], }, }, description: 'Text prompt to generate images', }, { displayName: 'Aspect Ratio', name: 'aspectRatio', type: 'options', options: [ { name: 'Square (1:1)', value: '1:1', description: 'Square images', }, { name: 'Portrait (9:16)', value: '9:16', description: 'Vertical images', }, { name: 'Landscape (16:9)', value: '16:9', description: 'Horizontal widescreen images', }, { name: 'Ultra Landscape (21:9)', value: '21:9', description: 'Ultra-wide horizontal images', }, ], default: '1:1', displayOptions: { show: { operation: ['imagine'], }, }, description: 'Aspect ratio of the generated images', }, { displayName: 'Process Mode', name: 'processMode', type: 'options', options: [ { name: 'Relax', value: 'relax', description: 'Lower priority but cheaper', }, { name: 'Fast', value: 'fast', description: 'Standard processing speed', }, { name: 'Turbo', value: 'turbo', description: 'Higher priority but more expensive', }, ], default: 'fast', displayOptions: { show: { operation: ['imagine', 'describe'], }, }, description: 'Processing speed priority', }, { displayName: 'Skip Prompt Check', name: 'skipPromptCheck', type: 'boolean', default: false, displayOptions: { show: { operation: ['imagine'], }, }, description: 'Whether to skip content filtering on prompts', }, { displayName: 'Origin Task ID', name: 'originTaskId', type: 'string', default: '', required: true, displayOptions: { show: { operation: ['upscale'], }, }, description: 'Task ID of the original Imagine operation', }, { displayName: 'Image Index', name: 'imageIndex', type: 'options', options: [ { name: 'Image 1', value: '1', description: 'First image in the grid', }, { name: 'Image 2', value: '2', description: 'Second image in the grid', }, { name: 'Image 3', value: '3', description: 'Third image in the grid', }, { name: 'Image 4', value: '4', description: 'Fourth image in the grid', }, ], default: '1', required: true, displayOptions: { show: { operation: ['upscale'], }, }, description: 'Which image to upscale from the original grid', }, { displayName: 'Image Input Method', name: 'imageInputMethod', type: 'options', options: [ { name: 'URL', value: 'url', }, { name: 'Binary Data', value: 'binaryData', }, ], default: 'url', displayOptions: { show: { operation: ['describe'], }, }, description: 'Method to input the image data', }, { displayName: 'Binary Property', name: 'binaryPropertyName', type: 'string', default: 'data', required: true, displayOptions: { show: { operation: ['describe'], imageInputMethod: ['binaryData'], }, }, description: 'Name of the binary property containing the image data', }, { displayName: 'Image URL', name: 'imageUrl', type: 'string', default: '', required: true, displayOptions: { show: { operation: ['describe'], imageInputMethod: ['url'], }, }, description: 'URL of the image to describe', }, { displayName: 'Advanced Options', name: 'advancedOptions', type: 'collection', placeholder: 'Add Option', default: {}, options: [ { displayName: 'Service Mode', name: 'serviceMode', type: 'options', options: [ { name: 'Public (PAYG)', value: 'public', description: 'Process under Pay-As-You-Go mode', }, { name: 'Private (HYA)', value: 'private', description: 'Process under Host-Your-Account mode', }, ], default: '', description: 'Choose how this task will be processed', }, { displayName: 'Bot ID', name: 'botId', type: 'number', default: 0, displayOptions: { show: { '/operation': ['describe'], }, }, description: 'Specify which Midjourney account will process this task (HYA Pro Plan only)', }, ], }, { displayName: 'Wait For Completion', name: 'waitForCompletion', type: 'boolean', default: false, description: 'Whether to wait for the operation to complete before continuing', }, { displayName: 'Max Retries', name: 'maxRetries', type: 'number', default: 60, description: 'Maximum number of retries to check task status', displayOptions: { show: { waitForCompletion: [true], }, }, }, { displayName: 'Retry Interval', name: 'retryInterval', type: 'number', default: 5000, description: 'Interval between retries in milliseconds', displayOptions: { show: { waitForCompletion: [true], }, }, }, ], }; } async execute() { var _a, _b; const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const operation = this.getNodeParameter('operation', i); const waitForCompletion = this.getNodeParameter('waitForCompletion', i, false); const advancedOptions = this.getNodeParameter('advancedOptions', i, {}); let response; const config = {}; if (advancedOptions.serviceMode) { config.service_mode = advancedOptions.serviceMode; } if (operation === 'imagine') { const prompt = this.getNodeParameter('prompt', i); const aspectRatio = this.getNodeParameter('aspectRatio', i, '1:1'); const processMode = this.getNodeParameter('processMode', i, 'fast'); const skipPromptCheck = this.getNodeParameter('skipPromptCheck', i, false); const requestBody = { model: 'midjourney', task_type: 'imagine', input: { prompt, aspect_ratio: aspectRatio, process_mode: processMode, skip_prompt_check: skipPromptCheck, }, config, }; response = await GenericFunctions_1.piApiRequest.call(this, 'POST', '/api/v1/task', requestBody); } else if (operation === 'upscale') { const originTaskId = this.getNodeParameter('originTaskId', i); const imageIndex = this.getNodeParameter('imageIndex', i); const requestBody = { model: 'midjourney', task_type: 'upscale', input: { origin_task_id: originTaskId, index: imageIndex, }, config, }; response = await GenericFunctions_1.piApiRequest.call(this, 'POST', '/api/v1/task', requestBody); } else if (operation === 'describe') { const imageInputMethod = this.getNodeParameter('imageInputMethod', i); const processMode = this.getNodeParameter('processMode', i, 'fast'); let imageUrl; if (imageInputMethod === 'url') { imageUrl = this.getNodeParameter('imageUrl', i); } else { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); if (binaryData.mimeType && !binaryData.mimeType.includes('image')) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'The provided binary data is not an image', { itemIndex: i }); } const base64String = Buffer.from(await this.helpers.getBinaryDataBuffer(i, binaryPropertyName)).toString('base64'); imageUrl = `data:${binaryData.mimeType};base64,${base64String}`; } const requestBody = { model: 'midjourney', task_type: 'describe', input: { image_url: imageUrl, process_mode: processMode, }, config, }; if (advancedOptions.botId) { requestBody.input.bot_id = advancedOptions.botId; } response = await GenericFunctions_1.piApiRequest.call(this, 'POST', '/api/v1/task', requestBody); } const taskId = (_a = response.data) === null || _a === void 0 ? void 0 : _a.task_id; if (!taskId) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to get a valid task ID from the API'); } let executionData; if (waitForCompletion) { const maxRetries = this.getNodeParameter('maxRetries', i, 60); const retryInterval = this.getNodeParameter('retryInterval', i, 5000); executionData = await GenericFunctions_1.waitForTaskCompletion.call(this, taskId, maxRetries, retryInterval); } else { executionData = { task_id: taskId, status: ((_b = response.data) === null || _b === void 0 ? void 0 : _b.status) || 'pending', }; } returnData.push({ json: executionData, }); } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message, }, }); continue; } throw error; } } return [returnData]; } } exports.PiAPIMidjourney = PiAPIMidjourney; //# sourceMappingURL=PiAPIMidjourney.node.js.map