🚚 Directorize all nodes

This commit is contained in:
Iván Ovejero
2021-11-17 14:35:57 +01:00
parent c98772c927
commit a7bb1463fb
95 changed files with 42 additions and 41 deletions

View File

@@ -0,0 +1,121 @@
{
"node": "n8n-nodes-base.function",
"nodeVersion": "1.0",
"codexVersion": "1.0",
"details": "The Function node allows you to execute JavaScript in your workflow. Unlike the Function Item node, this node does not operate on incoming node data per-item. Instead, you must iterate over multiple items of incoming data yourself. This can be useful if you're performing data transformation where you want to manipulate the number of items being outputted by the node (i.e. 1 item is inputted in with nested object, 10 items are outputted without any nested objects)",
"categories": [
"Development",
"Core Nodes"
],
"resources": {
"primaryDocumentation": [
{
"url": "https://docs.n8n.io/nodes/n8n-nodes-base.function/"
}
],
"generic": [
{
"label": "2021 Goals: Level Up Your Vocabulary With Vonage and n8n",
"icon": "🎯",
"url": "https://n8n.io/blog/2021-goals-level-up-your-vocabulary-with-vonage-and-n8n/"
},
{
"label": "Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide",
"icon": "🏭",
"url": "https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/"
},
{
"label": "2021: The Year to Automate the New You with n8n",
"icon": "☀️",
"url": "https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/"
},
{
"label": "Why business process automation with n8n can change your daily life",
"icon": "🧬",
"url": "https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/"
},
{
"label": "Why I chose n8n over Zapier in 2020",
"icon": "😍",
"url": "https://n8n.io/blog/why-i-chose-n8n-over-zapier-in-2020/"
},
{
"label": "How to host virtual coffee breaks with n8n",
"icon": "☕️",
"url": "https://n8n.io/blog/how-to-host-virtual-coffee-breaks-with-n8n/"
},
{
"label": "Automatically pulling and visualizing data with n8n",
"icon": "📈",
"url": "https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/"
},
{
"label": "Database Monitoring and Alerting with n8n",
"icon": "📡",
"url": "https://n8n.io/blog/database-monitoring-and-alerting-with-n8n/"
},
{
"label": "Supercharging your conference registration process with n8n",
"icon": "🎫",
"url": "https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/"
},
{
"label": "Creating triggers for n8n workflows using polling",
"icon": "⏲",
"url": "https://n8n.io/blog/creating-triggers-for-n8n-workflows-using-polling/"
},
{
"label": "How to build a low-code, self-hosted URL shortener in 3 steps",
"icon": "🔗",
"url": "https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/"
},
{
"label": "Build your own virtual assistant with n8n: A step by step guide",
"icon": "👦",
"url": "https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/"
},
{
"label": "How to automatically give kudos to contributors with GitHub, Slack, and n8n",
"icon": "👏",
"url": "https://n8n.io/blog/how-to-automatically-give-kudos-to-contributors-with-github-slack-and-n8n/"
},
{
"label": "5 workflow automations for Mattermost that we love at n8n",
"icon": "🤖",
"url": "https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/"
},
{
"label": "Tracking Time Spent in Meetings With Google Calendar, Twilio, and n8n",
"icon": "🗓",
"url": "https://n8n.io/blog/tracking-time-spent-in-meetings-with-google-calendar-twilio-and-n8n/"
},
{
"label": "Creating Error Workflows in n8n",
"icon": "🌪",
"url": "https://n8n.io/blog/creating-error-workflows-in-n8n/"
},
{
"label": "Sending Automated Congratulations with Google Sheets, Twilio, and n8n ",
"icon": "🙌",
"url": "https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/"
},
{
"label": "How Goomer automated their operations with over 200 n8n workflows",
"icon": "🛵",
"url": "https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/"
}
]
},
"alias": [
"Code",
"Javascript",
"Custom Code",
"Script",
"cpde"
],
"subcategories": {
"Core Nodes": [
"Data Transformation"
]
}
}

View File

@@ -0,0 +1,138 @@
import { IExecuteFunctions } from 'n8n-core';
import {
INodeExecutionData,
INodeType,
INodeTypeDescription,
NodeOperationError,
} from 'n8n-workflow';
const { NodeVM } = require('vm2');
export class Function implements INodeType {
description: INodeTypeDescription = {
displayName: 'Function',
name: 'function',
icon: 'fa:code',
group: ['transform'],
version: 1,
description: 'Run custom function code which gets executed once and allows you to add, remove, change and replace items',
defaults: {
name: 'Function',
color: '#FF9922',
},
inputs: ['main'],
outputs: ['main'],
properties: [
{
displayName: 'JavaScript Code',
name: 'functionCode',
typeOptions: {
alwaysOpenEditWindow: true,
editor: 'code',
rows: 10,
},
type: 'string',
default: `// Code here will run only once, no matter how many input items there are.
// More info and help: https://docs.n8n.io/nodes/n8n-nodes-base.function
// Loop over inputs and add a new field called 'myNewField' to the JSON of each one
for (item of items) {
item.json.myNewField = 1;
}
// You can write logs to the browser console
console.log('Done!');
return items;`,
description: 'The JavaScript code to execute.',
noDataExpression: true,
},
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
// const item = this.getInputData();
let items = this.getInputData();
// Copy the items as they may get changed in the functions
items = JSON.parse(JSON.stringify(items));
// Define the global objects for the custom function
const sandbox = {
getNodeParameter: this.getNodeParameter,
getWorkflowStaticData: this.getWorkflowStaticData,
helpers: this.helpers,
items,
// To be able to access data of other items
$item: (index: number) => this.getWorkflowDataProxy(index),
};
// Make it possible to access data via $node, $parameter, ...
// By default use data from first item
Object.assign(sandbox, sandbox.$item(0));
const mode = this.getMode();
const options = {
console: (mode === 'manual') ? 'redirect' : 'inherit',
sandbox,
require: {
external: false as boolean | { modules: string[] },
builtin: [] as string[],
},
};
if (process.env.NODE_FUNCTION_ALLOW_BUILTIN) {
options.require.builtin = process.env.NODE_FUNCTION_ALLOW_BUILTIN.split(',');
}
if (process.env.NODE_FUNCTION_ALLOW_EXTERNAL) {
options.require.external = { modules: process.env.NODE_FUNCTION_ALLOW_EXTERNAL.split(',') };
}
const vm = new NodeVM(options);
if (mode === 'manual') {
vm.on('console.log', this.sendMessageToUI);
}
// Get the code to execute
const functionCode = this.getNodeParameter('functionCode', 0) as string;
try {
// Execute the function code
items = (await vm.run(`module.exports = async function() {${functionCode}}()`, __dirname));
// Do very basic validation of the data
if (items === undefined) {
throw new NodeOperationError(this.getNode(), 'No data got returned. Always return an Array of items!');
}
if (!Array.isArray(items)) {
throw new NodeOperationError(this.getNode(), 'Always an Array of items has to be returned!');
}
for (const item of items) {
if (item.json === undefined) {
throw new NodeOperationError(this.getNode(), 'All returned items have to contain a property named "json"!');
}
if (typeof item.json !== 'object') {
throw new NodeOperationError(this.getNode(), 'The json-property has to be an object!');
}
if (item.binary !== undefined) {
if (Array.isArray(item.binary) || typeof item.binary !== 'object') {
throw new NodeOperationError(this.getNode(), 'The binary-property has to be an object!');
}
}
}
} catch (error) {
if (this.continueOnFail()) {
items=[{json:{ error: error.message }}];
} else {
return Promise.reject(error);
}
}
return this.prepareOutputData(items);
}
}