import { IExecuteFunctions } from 'n8n-core'; import { INodeExecutionData, INodeType, INodeTypeDescription, } from 'n8n-workflow'; import { exec } from 'child_process'; export interface IExecReturnData { exitCode: number; error?: Error; stderr: string; stdout: string; } /** * Promisifiy exec manually to also get the exit code * * @param {string} command * @returns {Promise} */ function execPromise(command: string): Promise { const returnData: IExecReturnData = { exitCode: 0, stderr: '', stdout: '', }; return new Promise((resolve, reject) => { exec(command, { cwd: process.cwd() }, (error, stdout, stderr) => { returnData.stdout = stdout.trim(); returnData.stderr = stderr.trim(); if (error) { returnData.error = error; } resolve(returnData); }).on('exit', code => { returnData.exitCode = code || 0; }); }); } export class ExecuteCommand implements INodeType { description: INodeTypeDescription = { displayName: 'Execute Command', name: 'executeCommand', icon: 'fa:terminal', group: ['transform'], version: 1, description: 'Executes a command on the host.', defaults: { name: 'Execute Command', color: '#886644', }, inputs: ['main'], outputs: ['main'], properties: [ { displayName: 'Execute Once', name: 'executeOnce', type: 'boolean', default: true, description: 'If activated it executes only once instead of once for each entry.', }, { displayName: 'Command', name: 'command', typeOptions: { rows: 5, }, type: 'string', default: '', placeholder: 'echo "test"', description: 'The command to execute', }, ] }; async execute(this: IExecuteFunctions): Promise { let items = this.getInputData(); let command: string; const executeOnce = this.getNodeParameter('executeOnce', 0) as boolean; if (executeOnce === true) { items = [items[0]]; } const returnItems: INodeExecutionData[] = []; for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { command = this.getNodeParameter('command', itemIndex) as string; const { // error, TODO: Later make it possible to select if it should fail on error or not exitCode, stdout, stderr, } = await execPromise(command); returnItems.push( { json: { exitCode, stderr, stdout, }, }, ); } return this.prepareOutputData(returnItems); } }