🔀 Merge master
This commit is contained in:
		
				commit
				
					
						b4cce8d55c
					
				
			
		
					 4 changed files with 99 additions and 47 deletions
				
			
		|  | @ -1,23 +1,56 @@ | ||||||
| import { ICredentialType, INodeProperties } from 'n8n-workflow'; | import { | ||||||
|  | 	IAuthenticateGeneric, | ||||||
|  | 	ICredentialTestRequest, | ||||||
|  | 	ICredentialType, | ||||||
|  | 	INodeProperties, | ||||||
|  | } from 'n8n-workflow'; | ||||||
| 
 | 
 | ||||||
| export class ExampleCredentials implements ICredentialType { | export class ExampleCredentials implements ICredentialType { | ||||||
| 	name = 'exampleCredentials'; | 	name = 'exampleCredentials'; | ||||||
| 	displayName = 'Example Credentials'; | 	displayName = 'Example Credentials'; | ||||||
| 	properties: INodeProperties[] = [ | 	properties: INodeProperties[] = [ | ||||||
| 		// Credential data to request from the user, saved in encrypted format.
 | 		// The credentials to get from user and save encrypted.
 | ||||||
| 		// Credential properties are defined exactly like node properties.
 | 		// Properties can be defined exactly in the same way
 | ||||||
|  | 		// as node properties.
 | ||||||
| 		{ | 		{ | ||||||
| 			displayName: 'Base URL', | 			displayName: 'User Name', | ||||||
| 			name: 'url', | 			name: 'username', | ||||||
| 			type: 'string', | 			type: 'string', | ||||||
| 			default: '', | 			default: '', | ||||||
| 			placeholder: 'https://example.com', |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			displayName: 'Access Token', | 			displayName: 'Password', | ||||||
| 			name: 'accessToken', | 			name: 'password', | ||||||
| 			type: 'string', | 			type: 'string', | ||||||
|  | 			typeOptions: { | ||||||
|  | 				password: true, | ||||||
|  | 			}, | ||||||
| 			default: '', | 			default: '', | ||||||
| 		}, | 		}, | ||||||
| 	]; | 	]; | ||||||
|  | 
 | ||||||
|  | 	// This credential is currently not used by any node directly
 | ||||||
|  | 	// but the HTTP Request node can use it to make requests.
 | ||||||
|  | 	// The credential is also testable due to the `test` property below
 | ||||||
|  | 	authenticate: IAuthenticateGeneric = { | ||||||
|  | 		type: 'generic', | ||||||
|  | 		properties: { | ||||||
|  | 			auth: { | ||||||
|  | 				username: '={{ $credentials.username }}', | ||||||
|  | 				password: '={{ $credentials.password }}', | ||||||
|  | 			}, | ||||||
|  | 			qs: { | ||||||
|  | 				// Send this as part of the query string
 | ||||||
|  | 				n8n: 'rocks', | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	// The block below tells how this credential can be tested
 | ||||||
|  | 	test: ICredentialTestRequest = { | ||||||
|  | 		request: { | ||||||
|  | 			baseURL: 'https://example.com/', | ||||||
|  | 			url: '', | ||||||
|  | 		}, | ||||||
|  | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,8 +1,7 @@ | ||||||
| import { | import { | ||||||
| 	ICredentialDataDecryptedObject, | 	IAuthenticateGeneric, | ||||||
| 	ICredentialTestRequest, | 	ICredentialTestRequest, | ||||||
| 	ICredentialType, | 	ICredentialType, | ||||||
| 	IHttpRequestOptions, |  | ||||||
| 	INodeProperties, | 	INodeProperties, | ||||||
| } from 'n8n-workflow'; | } from 'n8n-workflow'; | ||||||
| 
 | 
 | ||||||
|  | @ -17,12 +16,6 @@ export class HttpBinApi implements ICredentialType { | ||||||
| 			type: 'string', | 			type: 'string', | ||||||
| 			default: '', | 			default: '', | ||||||
| 		}, | 		}, | ||||||
| 		// {
 |  | ||||||
| 		// 	displayName: "API Key",
 |  | ||||||
| 		// 	name: "apiKey",
 |  | ||||||
| 		// 	type: "string",
 |  | ||||||
| 		// 	default: "",
 |  | ||||||
| 		// },
 |  | ||||||
| 		{ | 		{ | ||||||
| 			displayName: 'Domain', | 			displayName: 'Domain', | ||||||
| 			name: 'domain', | 			name: 'domain', | ||||||
|  | @ -31,26 +24,20 @@ export class HttpBinApi implements ICredentialType { | ||||||
| 		}, | 		}, | ||||||
| 	]; | 	]; | ||||||
| 
 | 
 | ||||||
| 	// authenticate = {
 | 	// This allows the credential to be used by other parts of n8n
 | ||||||
| 	// 	type: "headerAuth",
 | 	// stating how this credential is injected as part of the request
 | ||||||
| 	// 	properties: {
 | 	// An example is the Http Request node that can make generic calls
 | ||||||
| 	// 		name: "api-key",
 | 	// reusing this credential
 | ||||||
| 	// 		value: "={{$credentials.apiKey}}",
 | 	authenticate = { | ||||||
| 	// 	},
 | 		type: 'generic', | ||||||
| 	// } as IAuthenticateHeaderAuth;
 | 		properties: { | ||||||
| 
 | 			headers: { | ||||||
| 	authenticate = async ( | 				Authorization: '={{"Bearer " + $credentials.token}}', | ||||||
| 		credentials: ICredentialDataDecryptedObject, | 			}, | ||||||
| 		requestOptions: IHttpRequestOptions, | 		}, | ||||||
| 	): Promise<IHttpRequestOptions> => { | 	} as IAuthenticateGeneric; | ||||||
| 		const headers = requestOptions.headers || {}; |  | ||||||
| 		const authentication = { Authorization: `Bearer ${credentials.token}` }; |  | ||||||
| 		Object.assign(requestOptions, { |  | ||||||
| 			headers: { ...authentication, ...headers }, |  | ||||||
| 		}); |  | ||||||
| 		return requestOptions; |  | ||||||
| 	}; |  | ||||||
| 
 | 
 | ||||||
|  | 	// The block below tells how this credential can be tested
 | ||||||
| 	test: ICredentialTestRequest = { | 	test: ICredentialTestRequest = { | ||||||
| 		request: { | 		request: { | ||||||
| 			baseURL: '={{$credentials?.domain}}', | 			baseURL: '={{$credentials?.domain}}', | ||||||
|  |  | ||||||
|  | @ -1,5 +1,10 @@ | ||||||
| import { IExecuteFunctions } from 'n8n-core'; | import { IExecuteFunctions } from 'n8n-core'; | ||||||
| import { INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow'; | import { | ||||||
|  | 	INodeExecutionData, | ||||||
|  | 	INodeType, | ||||||
|  | 	INodeTypeDescription, | ||||||
|  | 	NodeOperationError, | ||||||
|  | } from 'n8n-workflow'; | ||||||
| 
 | 
 | ||||||
| export class ExampleNode implements INodeType { | export class ExampleNode implements INodeType { | ||||||
| 	description: INodeTypeDescription = { | 	description: INodeTypeDescription = { | ||||||
|  | @ -14,29 +19,56 @@ export class ExampleNode implements INodeType { | ||||||
| 		inputs: ['main'], | 		inputs: ['main'], | ||||||
| 		outputs: ['main'], | 		outputs: ['main'], | ||||||
| 		properties: [ | 		properties: [ | ||||||
| 			// Node properties that the user can see and change on the node.
 | 			// Node properties which the user gets displayed and
 | ||||||
|  | 			// can change on the node.
 | ||||||
| 			{ | 			{ | ||||||
| 				displayName: 'My String', | 				displayName: 'My String', | ||||||
| 				name: 'myString', | 				name: 'myString', | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
| 				default: '', | 				default: '', | ||||||
| 				placeholder: 'Placeholder value', | 				placeholder: 'Placeholder value', | ||||||
| 				description: 'This is a description', | 				description: 'The description text', | ||||||
| 			}, | 			}, | ||||||
| 		], | 		], | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | 	// The function below is responsible for actually doing whatever this node
 | ||||||
|  | 	// is supposed to do. In this case, we're just appending the `myString` property
 | ||||||
|  | 	// with whatever the user has entered.
 | ||||||
|  | 	// You can make async calls and use `await`.
 | ||||||
| 	async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> { | 	async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> { | ||||||
| 		const items = this.getInputData(); | 		const items = this.getInputData(); | ||||||
| 
 | 
 | ||||||
| 		// The node iterates over all input items and adds the key "myString" with the
 | 		let item: INodeExecutionData; | ||||||
| 		// value the parameter "myString" resolves to. (This could be a different value
 | 		let myString: string; | ||||||
| 		// for each item in case it contains an expression.)
 | 
 | ||||||
|  | 		// Iterates 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++) { | 		for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { | ||||||
| 			const myString = this.getNodeParameter('myString', itemIndex, '') as string; | 			try { | ||||||
| 			const item = items[itemIndex]; | 				myString = this.getNodeParameter('myString', itemIndex, '') as string; | ||||||
|  | 				item = items[itemIndex]; | ||||||
| 
 | 
 | ||||||
| 				item.json['myString'] = myString; | 				item.json['myString'] = myString; | ||||||
|  | 			} catch (error) { | ||||||
|  | 				// This node should never fail but we want to showcase how
 | ||||||
|  | 				// to handle errors.
 | ||||||
|  | 				if (this.continueOnFail()) { | ||||||
|  | 					items.push({ json: this.getInputData(itemIndex)[0].json, error }); | ||||||
|  | 				} else { | ||||||
|  | 					// Adding `itemIndex` allows other workflows to handle this error
 | ||||||
|  | 					if (error.context) { | ||||||
|  | 						// If the error thrown already contains the context property,
 | ||||||
|  | 						// only append the itemIndex
 | ||||||
|  | 						error.context.itemIndex = itemIndex; | ||||||
|  | 						throw error; | ||||||
|  | 					} | ||||||
|  | 					throw new NodeOperationError(this.getNode(), error, { | ||||||
|  | 						itemIndex, | ||||||
|  | 					}); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return this.prepareOutputData(items); | 		return this.prepareOutputData(items); | ||||||
|  |  | ||||||
|  | @ -43,8 +43,8 @@ | ||||||
|     "@typescript-eslint/parser": "^5.29.0", |     "@typescript-eslint/parser": "^5.29.0", | ||||||
|     "eslint-plugin-n8n-nodes-base": "^1.2.0", |     "eslint-plugin-n8n-nodes-base": "^1.2.0", | ||||||
|     "gulp": "^4.0.2", |     "gulp": "^4.0.2", | ||||||
|     "n8n-core": "~0.123.0", |     "n8n-core": "^0.124.0", | ||||||
|     "n8n-workflow": "~0.105.0", |     "n8n-workflow": "^0.106.0", | ||||||
|     "prettier": "^2.7.1", |     "prettier": "^2.7.1", | ||||||
|     "tslint": "^6.1.2", |     "tslint": "^6.1.2", | ||||||
|     "typescript": "~4.6.0" |     "typescript": "~4.6.0" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue