n8n/packages/node-dev
Jan Oberhauser 0da398b0e4
Nodes as JSON and authentication redesign (#2401)
*  change FE to handle new object type

* 🚸 improve UX of handling invalid credentials

* 🚧 WIP

* 🎨 fix typescript issues

* 🐘 add migrations for all supported dbs

* ✏️ add description to migrations

*  add credential update on import

*  resolve after merge issues

* 👕 fix lint issues

*  check credentials on workflow create/update

* update interface

* 👕 fix ts issues

*  adaption to new credentials UI

* 🐛 intialize cache on BE for credentials check

* 🐛 fix undefined oldCredentials

* 🐛 fix deleting credential

* 🐛 fix check for undefined keys

* 🐛 fix disabling edit in execution

* 🎨 just show credential name on execution view

* ✏️  remove TODO

*  implement review suggestions

*  add cache to getCredentialsByType

*  use getter instead of cache

* ✏️ fix variable name typo

* 🐘 include waiting nodes to migrations

* 🐛 fix reverting migrations command

*  update typeorm command

*  create db:revert command

* 👕 fix lint error

*  Add optional authenticate method to credentials

*  Simplify code and add authentication support to MattermostApi

* 👕 Fix lint issue

*  Add support to own-mode

* 👕 Fix lint issue

*  Add support for predefined auth types bearer and headerAuth

*  Make sure that DateTime Node always returns strings

*  Add support for moment types to If Node

*  Make it possible for HTTP Request Node to use all credential types

*  Add basicAuth support

* Add a new dropcontact node

*  First basic implementation of mainly JSON based nodes

*  Add fixedCollection support, added value parameter and
expression support for value and property

* Improvements to #2389

*  Add credentials verification

*  Small improvement

*  set default time to 45 seconds

*  Add support for preSend and postReceive methods

*  Add lodash merge and set depedency to workflow

* 👕 Fix lint issue

*  Improvements

*  Improvements

*  Improvements

*  Improvements

*  Improvements

* 🐛 Set siren and language correctly

*  Add support for requestDefaults

*  Add support for baseURL to httpRequest

*  Move baseURL to correct location

*  Add support for options loading

* 🐛 Fix error with fullAccess nodes

*  Add credential test functionality

* 🐛 Fix issue with OAuth autentication and lint issue

*  Fix build issue

* 🐛 Fix issue that url got always overwritten to empty

*  Add pagination support

*  Code fix required after merge

*  Remove not needed imports

*  Fix credential test

*  Add expression support for request properties and $self
support on properties

*  Rename $self to $value

* 👕 Fix lint issue

*  Add example how to send data in path

*  Make it possible to not sent in dot notation

*  Add support for postReceive:rootProperty

*  Fix typo

*  Add support for postReceive:set

*  Some fixes

*  Small improvement

* ;zap: Separate RoutingNode code

*  Simplify code and fix bug

*  Remove unused code

*  Make it possible to define "request" and "requestProperty" on
options

* 👕 Fix lint issue

*  Change $credentials variables name

*  Enable expressions and access to credentials in requestDefaults

*  Make parameter option loading use RoutingNode.makeRoutingRequest

*  Allow requestOperations overwrite on LoadOptions

*  Make it possible to access current node parameters in loadOptions

*  Rename parameters variable to make future proof

*  Make it possible to use offset-pagination with body

*  Add support for queryAuth

*  Never return more items than requested

*  Make it possible to overwrite requestOperations on parameter
and option level

* 👕 Fix lint issue

*  Allow simplified auth also with regular nodes

*  Add support for receiving binary data

* 🐛 Fix example node

*  Rename property "name" to "displayName" in loadOptions

*  Send data by default as "query" if nothing is set

*  Rename $self to $parent

*  Change to work with INodeExecutionData instead of IDataObject

*  Improve binaryData handling

*  Property design improvements

*  Fix property name

* 🚨 Add some tests

*  Add also test for request

*  Improve test and fix issues

*  Improvements to loadOptions

*  Normalize loadOptions with rest of code

*  Add info text

*  Add support for $value in postReceive

* 🚨 Add tests for RoutingNode.runNode

*  Remove TODOs and make url property optional

*  Fix bug and lint issue

* 🐛 Fix bug that not the correct property got used

* 🚨 Add tests for CredentialsHelper.authenticate

*  Improve code and resolve expressions also everywhere for
loadOptions and credential test requests

*  Make it possible to define multiple preSend and postReceive
actions

*  Allow to define tests on credentials

*  Remove test data

* ⬆️ Update package-lock.json file

*  Remove old not longer used code

Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com>
Co-authored-by: Mutasem <mutdmour@gmail.com>
Co-authored-by: PaulineDropcontact <pauline@dropcontact.io>
Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
2022-02-05 22:55:43 +01:00
..
bin Rename n8n-node-dev cli command file 2019-08-28 12:48:29 +02:00
commands 🎨 Set up linting and formatting (#2120) 2021-08-29 20:58:11 +02:00
src 👕 Fix lint issue 2021-09-18 23:03:52 +02:00
templates Simplify more property types in credentials classes (#2211) 2021-10-07 23:07:56 +02:00
LICENSE.md 📚 License text fix 2020-09-15 07:55:09 +02:00
package.json 🔖 Release n8n-node-dev@0.42.0 2022-01-30 14:07:37 +00:00
README.md Deprecate step size and node color (#2586) 2021-12-23 13:30:35 +01:00
tsconfig.json Nodes as JSON and authentication redesign (#2401) 2022-02-05 22:55:43 +01:00
tslint.json 👕 Fix lint issue 2020-10-22 15:46:03 +02:00

n8n-node-dev

n8n.io - Workflow Automation

Currently very simple and not very sophisticated CLI which makes it easier to create credentials and nodes in TypeScript for n8n.

npm install n8n-node-dev -g

Contents

Usage

The commandline tool can be started with n8n-node-dev <COMMAND>

Commands

The following commands exist:

build

Builds credentials and nodes in the current folder and copies them into the n8n custom extension folder (~/.n8n/custom/) unless destination path is overwritten with --destination <FOLDER_PATH>

When "--watch" gets set it starts in watch mode and automatically builds and copies files whenever they change. To stop press "ctrl + c".

new

Creates new basic credentials or node of the selected type to have a first starting point.

Create a node

The easiest way to create a new node is via the "n8n-node-dev" cli. It sets up all the basics.

A n8n node is a JavaScript file (normally written in TypeScript) which describes some basic information (like name, description, ...) and also at least one method. Depending on which method got implemented defines if it is a a regular-, trigger- or webhook-node.

A simple regular node which:

  • defines one node property
  • sets its value do all items it receives

would look like this:

File named: MyNode.node.ts

import { IExecuteFunctions } from 'n8n-core';
import {
	INodeExecutionData,
	INodeType,
	INodeTypeDescription,
} from 'n8n-workflow';


export class MyNode implements INodeType {
	description: INodeTypeDescription = {
		displayName: 'My Node',
		name: 'myNode',
		group: ['transform'],
		version: 1,
		description: 'Adds "myString" on all items to defined value.',
		defaults: {
			name: 'My Node',
			color: '#772244',
		},
		inputs: ['main'],
		outputs: ['main'],
		properties: [
			// Node properties which the user gets displayed and
			// can change on the node.
			{
				displayName: 'My String',
				name: 'myString',
				type: 'string',
				default: '',
				placeholder: 'Placeholder value',
				description: 'The description text',
			}
		]
	};


	async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {

		const items = this.getInputData();

		let item: INodeExecutionData;
		let myString: string;

		// Itterates over all input items and add the key "myString" with the
		// value the parameter "myString" resolves to.
		// (This could be a different value for each item in case it contains an expression)
		for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
			myString = this.getNodeParameter('myString', itemIndex, '') as string;
			item = items[itemIndex];

			item.json['myString'] = myString;
		}

		return this.prepareOutputData(items);

	}
}

The "description" property has to be set on all nodes because it contains all the base information. Additionally do all nodes have to have exactly one of the following methods defined which contains the actual logic:

Regular node

Method get called when the workflow gets executed

  • execute: Executed once no matter how many items
  • executeSingle: Executed once for every item

By default always execute should be used especially when creating a third-party integration. The reason for that is that it is way more flexible and allows to, for example, return a different amount of items than it received as input. This is very important when a node should query data like return all users. In that case, does the node normally just receive one input-item but returns as many as users exist. So in doubt always execute should be used!

Trigger node

Method gets called once when the workflow gets activated. It can then trigger workflow runs which data it provides by itself.

  • trigger

Webhook node

Method gets called when webhook gets called.

  • webhook

Node Type

Property overview

  • description [required]: Describes the node like its name, properties, hooks, ... see Node Type Description bellow.
  • execute [optional]: Method get called when the workflow gets executed (once).
  • executeSingle [optional]: Method get called when the workflow gets executed (once for every item).
  • hooks [optional]: The hook methods.
  • methods [optional]: Additional methods. Currently only "loadOptions" exists which allows loading options for parameters from external services
  • trigger [optional]: Method gets called once when the workflow gets activated.
  • webhook [optional]: Method gets called when webhook gets called.
  • webhookMethods [optional]: Methods to setup webhooks on external services.

Node Type Description

The following properties can be set in the node description:

  • credentials [optional]: Credentials the node requests access to
  • defaults [required]: Default "name" and "color" to set on node when it gets created
  • displayName [required]: Name to display users in Editor UI
  • description [required]: Description to display users in Editor UI
  • group [required]: Node group for example "transform" or "trigger"
  • hooks [optional]: Methods to execute at different points in time like when the workflow gets activated or deactivated
  • icon [optional]: Icon to display (can be an icon or a font awsome icon)
  • inputs [required]: Types of inputs the node has (currently only "main" exists) and the amount
  • outputs [required]: Types of outputs the node has (currently only "main" exists) and the amount
  • outputNames [optional]: In case a node has multiple outputs names can be set that users know what data to expect
  • maxNodes [optional]: If not an unlimited amount of nodes of that type can exist in a workflow the max-amount can be specified
  • name [required]: Name of the node (for n8n to use internally, in camelCase)
  • properties [required]: Properties which get displayed in the Editor UI and can be set by the user
  • subtitle [optional]: Text which should be displayed underneath the name of the node in the Editor UI (can be an expression)
  • version [required]: Version of the node. Currently always "1" (integer). For future usage, does not get used yet.
  • webhooks [optional]: Webhooks the node should listen to

Node Properties

The following properties can be set in the node properties:

  • default [required]: Default value of the property
  • description [required]: Description that is displayed to users in the Editor UI
  • displayName [required]: Name that is displayed to users in the Editor UI
  • displayOptions [optional]: Defines logic to decide if a property should be displayed or not
  • name [required]: Name of the property (for n8n to use internally, in camelCase)
  • options [optional]: The options the user can select when type of property is "collection", "fixedCollection" or "options"
  • placeholder [optional]: Placeholder text that is displayed to users in the Editor UI
  • type [required]: Type of the property. If it is for example a "string", "number", ...
  • typeOptions [optional]: Additional options for type. Like for example the min or max value of a number
  • required [optional]: Defines if the value has to be set or if it can stay empty

Node Property Options

The following properties can be set in the node property options.

All properties are optional. However, most only work when the node-property is of a specfic type.

  • alwaysOpenEditWindow [type: string]: If set then the "Editor Window" will always open when the user tries to edit the field. Helpful if long text is typically used in the property.
  • loadOptionsMethod [type: options]: Method to use to load options from an external service
  • maxValue [type: number]: Maximum value of the number
  • minValue [type: number]: Minimum value of the number
  • multipleValues [type: all]: If set the property gets turned into an Array and the user can add multiple values
  • multipleValueButtonText [type: all]: Custom text for add button in case "multipleValues" got set
  • numberPrecision [type: number]: The precision of the number. By default it is "0" and will so only allow integers.
  • password [type: string]: If a password field should be displayed (normally only used by credentials because all node data is not encrypted and get saved in clear-text)
  • rows [type: string]: Number of rows the input field should have. By default it is "1"

License

Apache 2.0 with Commons Clause

Additional information about license can be found in the FAQ