mirror of
				https://github.com/n8n-io/n8n-nodes-starter.git
				synced 2025-10-30 23:02:25 -05:00 
			
		
		
		
	Outgrow Trigger V1
This commit is contained in:
		
					parent
					
						
							
								e863c55657
							
						
					
				
			
			
				commit
				
					
						24f7ae4a19
					
				
			
		
					 14 changed files with 564 additions and 585 deletions
				
			
		
							
								
								
									
										79
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										79
									
								
								README.md
									
										
									
									
									
								
							|  | @ -1,48 +1,57 @@ | ||||||
|  | # Outgrow Trigger Node for n8n | ||||||
| 
 | 
 | ||||||
| # n8n-nodes-starter | [](https://n8n.io/integrations) | ||||||
| 
 | 
 | ||||||
| This repo contains example nodes to help you get started building your own custom integrations for [n8n](https://n8n.io). It includes the node linter and other dependencies. | Trigger node that fetches leads from Outgrow calculators at configurable intervals. | ||||||
| 
 | 
 | ||||||
| To make your custom node available to the community, you must create it as an npm package, and [submit it to the npm registry](https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry). |  *(Optional: Add screenshot later)* | ||||||
| 
 | 
 | ||||||
| If you would like your node to be available on n8n cloud you can also [submit your node for verification](https://docs.n8n.io/integrations/creating-nodes/deploy/submit-community-nodes/). | ## Features | ||||||
|  | 
 | ||||||
|  | - 🕒 **Polling API**: Checks for new leads at customizable intervals (default: 5 minutes) | ||||||
|  | - 📋 **Calculator Selection**: Dynamic dropdown of available calculators | ||||||
|  | - 🔔 **Smart Notifications**: Clear "no leads" messages in the UI | ||||||
|  | - ⚙️ **Manual Trigger**: Instant API calls for testing | ||||||
| 
 | 
 | ||||||
| ## Prerequisites | ## Prerequisites | ||||||
| 
 | 
 | ||||||
| You need the following installed on your development machine: | - Outgrow account with API access | ||||||
|  | - API key from [Outgrow Settings](https://app.outgrow.co/settings/api) | ||||||
| 
 | 
 | ||||||
| * [git](https://git-scm.com/downloads) | ## Installation | ||||||
| * Node.js and npm. Minimum version Node 20. You can find instructions on how to install both using nvm (Node Version Manager) for Linux, Mac, and WSL [here](https://github.com/nvm-sh/nvm). For Windows users, refer to Microsoft's guide to [Install NodeJS on Windows](https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-windows). |  | ||||||
| * Install n8n with: |  | ||||||
|   ``` |  | ||||||
|   npm install n8n -g |  | ||||||
|   ``` |  | ||||||
| * Recommended: follow n8n's guide to [set up your development environment](https://docs.n8n.io/integrations/creating-nodes/build/node-development-environment/). |  | ||||||
| 
 | 
 | ||||||
| ## Using this starter | 1. Add the node to your n8n instance | ||||||
|  | 2. Configure Outgrow API credentials: | ||||||
|  |    - Navigate to **Credentials > Add New > Outgrow API** | ||||||
|  |    - Enter your API key | ||||||
| 
 | 
 | ||||||
| These are the basic steps for working with the starter. For detailed guidance on creating and publishing nodes, refer to the [documentation](https://docs.n8n.io/integrations/creating-nodes/). | ## Node Configuration | ||||||
| 
 | 
 | ||||||
| 1. [Generate a new repository](https://github.com/n8n-io/n8n-nodes-starter/generate) from this template repository. | ### Parameters | ||||||
| 2. Clone your new repo: | | Field               | Required | Description                                                                 | | ||||||
|    ``` | |---------------------|----------|-----------------------------------------------------------------------------| | ||||||
|    git clone https://github.com/<your organization>/<your-repo-name>.git | | **Calculator**      | Yes      | Select which Outgrow calculator to monitor                                  | | ||||||
|    ``` | | **Polling Interval**| No       | Frequency (in minutes) to check for new leads (default: 5)                  | | ||||||
| 3. Run `npm i` to install dependencies. |  | ||||||
| 4. Open the project in your editor. |  | ||||||
| 5. Browse the examples in `/nodes` and `/credentials`. Modify the examples, or replace them with your own nodes. |  | ||||||
| 6. Update the `package.json` to match your details. |  | ||||||
| 7. Run `npm run lint` to check for errors or `npm run lintfix` to automatically fix errors when possible. |  | ||||||
| 8. Test your node locally. Refer to [Run your node locally](https://docs.n8n.io/integrations/creating-nodes/test/run-node-locally/) for guidance. |  | ||||||
| 9. Replace this README with documentation for your node. Use the [README_TEMPLATE](README_TEMPLATE.md) to get started. |  | ||||||
| 10. Update the LICENSE file to use your details. |  | ||||||
| 11. [Publish](https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry) your package to npm. |  | ||||||
| 
 | 
 | ||||||
| ## More information | ## Usage Examples | ||||||
| 
 | 
 | ||||||
| Refer to our [documentation on creating nodes](https://docs.n8n.io/integrations/creating-nodes/) for detailed information on building your own nodes. | ### Basic Automation | ||||||
| 
 | ```json | ||||||
| ## License | { | ||||||
| 
 |   "workflow": { | ||||||
| [MIT](https://github.com/n8n-io/n8n-nodes-starter/blob/master/LICENSE.md) |     "nodes": [ | ||||||
|  |       { | ||||||
|  |         "parameters": { | ||||||
|  |           "calcId": "{{CALCULATOR_ID}}", | ||||||
|  |           "pollingInterval": 10 | ||||||
|  |         }, | ||||||
|  |         "name": "Outgrow Trigger", | ||||||
|  |         "type": "outgrowTrigger", | ||||||
|  |         "typeVersion": 1 | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         // Connect to other nodes (Email, Slack, etc.) | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -1,59 +0,0 @@ | ||||||
| import { |  | ||||||
| 	IAuthenticateGeneric, |  | ||||||
| 	ICredentialTestRequest, |  | ||||||
| 	ICredentialType, |  | ||||||
| 	INodeProperties, |  | ||||||
| } from 'n8n-workflow'; |  | ||||||
| 
 |  | ||||||
| export class ExampleCredentialsApi implements ICredentialType { |  | ||||||
| 	name = 'exampleCredentialsApi'; |  | ||||||
| 	displayName = 'Example Credentials API'; |  | ||||||
| 
 |  | ||||||
| 	documentationUrl = 'https://your-docs-url'; |  | ||||||
| 
 |  | ||||||
| 	properties: INodeProperties[] = [ |  | ||||||
| 		// The credentials to get from user and save encrypted.
 |  | ||||||
| 		// Properties can be defined exactly in the same way
 |  | ||||||
| 		// as node properties.
 |  | ||||||
| 		{ |  | ||||||
| 			displayName: 'User Name', |  | ||||||
| 			name: 'username', |  | ||||||
| 			type: 'string', |  | ||||||
| 			default: '', |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			displayName: 'Password', |  | ||||||
| 			name: 'password', |  | ||||||
| 			type: 'string', |  | ||||||
| 			typeOptions: { |  | ||||||
| 				password: true, |  | ||||||
| 			}, |  | ||||||
| 			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,50 +0,0 @@ | ||||||
| import { |  | ||||||
| 	IAuthenticateGeneric, |  | ||||||
| 	ICredentialTestRequest, |  | ||||||
| 	ICredentialType, |  | ||||||
| 	INodeProperties, |  | ||||||
| } from 'n8n-workflow'; |  | ||||||
| 
 |  | ||||||
| export class HttpBinApi implements ICredentialType { |  | ||||||
| 	name = 'httpbinApi'; |  | ||||||
| 	displayName = 'HttpBin API'; |  | ||||||
| 	documentationUrl = 'https://your-docs-url'; |  | ||||||
| 	properties: INodeProperties[] = [ |  | ||||||
| 		{ |  | ||||||
| 			displayName: 'Token', |  | ||||||
| 			name: 'token', |  | ||||||
| 			type: 'string', |  | ||||||
| 			default: '', |  | ||||||
| 			typeOptions: { |  | ||||||
| 				password: true, |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			displayName: 'Domain', |  | ||||||
| 			name: 'domain', |  | ||||||
| 			type: 'string', |  | ||||||
| 			default: 'https://httpbin.org', |  | ||||||
| 		}, |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	// This allows the credential to be used by other parts of n8n
 |  | ||||||
| 	// stating how this credential is injected as part of the request
 |  | ||||||
| 	// An example is the Http Request node that can make generic calls
 |  | ||||||
| 	// reusing this credential
 |  | ||||||
| 	authenticate: IAuthenticateGeneric = { |  | ||||||
| 		type: 'generic', |  | ||||||
| 		properties: { |  | ||||||
| 			headers: { |  | ||||||
| 				Authorization: '={{"Bearer " + $credentials.token}}', |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	// The block below tells how this credential can be tested
 |  | ||||||
| 	test: ICredentialTestRequest = { |  | ||||||
| 		request: { |  | ||||||
| 			baseURL: '={{$credentials?.domain}}', |  | ||||||
| 			url: '/bearer', |  | ||||||
| 		}, |  | ||||||
| 	}; |  | ||||||
| } |  | ||||||
							
								
								
									
										22
									
								
								credentials/outgrowApi.credentials.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								credentials/outgrowApi.credentials.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | ||||||
|  | import { | ||||||
|  | 	ICredentialType, | ||||||
|  | 	INodeProperties, | ||||||
|  | } from 'n8n-workflow'; | ||||||
|  | 
 | ||||||
|  | export class outgrowApi implements ICredentialType { | ||||||
|  | 	name = 'outgrowApi'; // 👈 Must match what you use in the node
 | ||||||
|  | 	displayName = 'Outgrow API'; | ||||||
|  | 	documentationUrl = 'https://docs.n8n.io/integrations/creating-nodes/build/credentials/'; | ||||||
|  | 	properties: INodeProperties[] = [ | ||||||
|  | 		{ | ||||||
|  | 			displayName: 'API Key', | ||||||
|  | 			name: 'apiKey', | ||||||
|  | 			type: 'string', | ||||||
|  | 			default: '', | ||||||
|  | 			required: true, | ||||||
|  | 			description: 'Your Outgrow API key', | ||||||
|  | 		}, | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	// No built-in auth here since we inject key manually in node code
 | ||||||
|  | } | ||||||
|  | @ -1,77 +0,0 @@ | ||||||
| import type { |  | ||||||
| 	IExecuteFunctions, |  | ||||||
| 	INodeExecutionData, |  | ||||||
| 	INodeType, |  | ||||||
| 	INodeTypeDescription, |  | ||||||
| } from 'n8n-workflow'; |  | ||||||
| import { NodeConnectionType, NodeOperationError } from 'n8n-workflow'; |  | ||||||
| 
 |  | ||||||
| export class ExampleNode implements INodeType { |  | ||||||
| 	description: INodeTypeDescription = { |  | ||||||
| 		displayName: 'Example Node', |  | ||||||
| 		name: 'exampleNode', |  | ||||||
| 		group: ['transform'], |  | ||||||
| 		version: 1, |  | ||||||
| 		description: 'Basic Example Node', |  | ||||||
| 		defaults: { |  | ||||||
| 			name: 'Example Node', |  | ||||||
| 		}, |  | ||||||
| 		inputs: [NodeConnectionType.Main], |  | ||||||
| 		outputs: [NodeConnectionType.Main], |  | ||||||
| 		usableAsTool: true, |  | ||||||
| 		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', |  | ||||||
| 			}, |  | ||||||
| 		], |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	// 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[][]> { |  | ||||||
| 		const items = this.getInputData(); |  | ||||||
| 
 |  | ||||||
| 		let item: INodeExecutionData; |  | ||||||
| 		let myString: string; |  | ||||||
| 
 |  | ||||||
| 		// 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++) { |  | ||||||
| 			try { |  | ||||||
| 				myString = this.getNodeParameter('myString', itemIndex, '') as string; |  | ||||||
| 				item = items[itemIndex]; |  | ||||||
| 
 |  | ||||||
| 				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, pairedItem: itemIndex }); |  | ||||||
| 				} 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 [items]; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -1,18 +0,0 @@ | ||||||
| { |  | ||||||
| 	"node": "n8n-nodes-base.httpbin", |  | ||||||
| 	"nodeVersion": "1.0", |  | ||||||
| 	"codexVersion": "1.0", |  | ||||||
| 	"categories": ["Development", "Developer Tools"], |  | ||||||
| 	"resources": { |  | ||||||
| 		"credentialDocumentation": [ |  | ||||||
| 			{ |  | ||||||
| 				"url": "http://httpbin.org/#/Auth/get_bearer" |  | ||||||
| 			} |  | ||||||
| 		], |  | ||||||
| 		"primaryDocumentation": [ |  | ||||||
| 			{ |  | ||||||
| 				"url": "http://httpbin.org/" |  | ||||||
| 			} |  | ||||||
| 		] |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -1,63 +0,0 @@ | ||||||
| import { INodeType, INodeTypeDescription, NodeConnectionType } from 'n8n-workflow'; |  | ||||||
| import { httpVerbFields, httpVerbOperations } from './HttpVerbDescription'; |  | ||||||
| 
 |  | ||||||
| export class HttpBin implements INodeType { |  | ||||||
| 	description: INodeTypeDescription = { |  | ||||||
| 		displayName: 'HttpBin', |  | ||||||
| 		name: 'httpBin', |  | ||||||
| 		icon: { light: 'file:httpbin.svg', dark: 'file:httpbin.svg' }, |  | ||||||
| 		group: ['transform'], |  | ||||||
| 		version: 1, |  | ||||||
| 		subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', |  | ||||||
| 		description: 'Interact with HttpBin API', |  | ||||||
| 		defaults: { |  | ||||||
| 			name: 'HttpBin', |  | ||||||
| 		}, |  | ||||||
| 		inputs: [NodeConnectionType.Main], |  | ||||||
| 		outputs: [NodeConnectionType.Main], |  | ||||||
| 		usableAsTool: true, |  | ||||||
| 		credentials: [ |  | ||||||
| 			{ |  | ||||||
| 				name: 'httpbinApi', |  | ||||||
| 				required: false, |  | ||||||
| 			}, |  | ||||||
| 		], |  | ||||||
| 		requestDefaults: { |  | ||||||
| 			baseURL: 'https://httpbin.org', |  | ||||||
| 			url: '', |  | ||||||
| 			headers: { |  | ||||||
| 				Accept: 'application/json', |  | ||||||
| 				'Content-Type': 'application/json', |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		/** |  | ||||||
| 		 * In the properties array we have two mandatory options objects required |  | ||||||
| 		 * |  | ||||||
| 		 * [Resource & Operation] |  | ||||||
| 		 * |  | ||||||
| 		 * https://docs.n8n.io/integrations/creating-nodes/code/create-first-node/#resources-and-operations
 |  | ||||||
| 		 * |  | ||||||
| 		 * In our example, the operations are separated into their own file (HTTPVerbDescription.ts) |  | ||||||
| 		 * to keep this class easy to read. |  | ||||||
| 		 * |  | ||||||
| 		 */ |  | ||||||
| 		properties: [ |  | ||||||
| 			{ |  | ||||||
| 				displayName: 'Resource', |  | ||||||
| 				name: 'resource', |  | ||||||
| 				type: 'options', |  | ||||||
| 				noDataExpression: true, |  | ||||||
| 				options: [ |  | ||||||
| 					{ |  | ||||||
| 						name: 'HTTP Verb', |  | ||||||
| 						value: 'httpVerb', |  | ||||||
| 					}, |  | ||||||
| 				], |  | ||||||
| 				default: 'httpVerb', |  | ||||||
| 			}, |  | ||||||
| 
 |  | ||||||
| 			...httpVerbOperations, |  | ||||||
| 			...httpVerbFields, |  | ||||||
| 		], |  | ||||||
| 	}; |  | ||||||
| } |  | ||||||
|  | @ -1,250 +0,0 @@ | ||||||
| import { INodeProperties } from 'n8n-workflow'; |  | ||||||
| 
 |  | ||||||
| // When the resource `httpVerb` is selected, this `operation` parameter will be shown.
 |  | ||||||
| export const httpVerbOperations: INodeProperties[] = [ |  | ||||||
| 	{ |  | ||||||
| 		displayName: 'Operation', |  | ||||||
| 		name: 'operation', |  | ||||||
| 		type: 'options', |  | ||||||
| 		noDataExpression: true, |  | ||||||
| 
 |  | ||||||
| 		displayOptions: { |  | ||||||
| 			show: { |  | ||||||
| 				resource: ['httpVerb'], |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		options: [ |  | ||||||
| 			{ |  | ||||||
| 				name: 'GET', |  | ||||||
| 				value: 'get', |  | ||||||
| 				description: 'Perform a GET request', |  | ||||||
| 				action: 'Perform a GET request', |  | ||||||
| 				routing: { |  | ||||||
| 					request: { |  | ||||||
| 						method: 'GET', |  | ||||||
| 						url: '/get', |  | ||||||
| 					}, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 			{ |  | ||||||
| 				name: 'DELETE', |  | ||||||
| 				value: 'delete', |  | ||||||
| 				description: 'Perform a DELETE request', |  | ||||||
| 				action: 'Perform a DELETE request', |  | ||||||
| 				routing: { |  | ||||||
| 					request: { |  | ||||||
| 						method: 'DELETE', |  | ||||||
| 						url: '/delete', |  | ||||||
| 					}, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		], |  | ||||||
| 		default: 'get', |  | ||||||
| 	}, |  | ||||||
| ]; |  | ||||||
| 
 |  | ||||||
| // Here we define what to show when the `get` operation is selected.
 |  | ||||||
| // We do that by adding `operation: ["get"]` to `displayOptions.show`
 |  | ||||||
| const getOperation: INodeProperties[] = [ |  | ||||||
| 	{ |  | ||||||
| 		displayName: 'Type of Data', |  | ||||||
| 		name: 'typeofData', |  | ||||||
| 		default: 'queryParameter', |  | ||||||
| 		description: 'Select type of data to send [Query Parameters]', |  | ||||||
| 		displayOptions: { |  | ||||||
| 			show: { |  | ||||||
| 				resource: ['httpVerb'], |  | ||||||
| 				operation: ['get'], |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		type: 'options', |  | ||||||
| 		options: [ |  | ||||||
| 			{ |  | ||||||
| 				name: 'Query', |  | ||||||
| 				value: 'queryParameter', |  | ||||||
| 			}, |  | ||||||
| 		], |  | ||||||
| 		required: true, |  | ||||||
| 	}, |  | ||||||
| 	{ |  | ||||||
| 		displayName: 'Query Parameters', |  | ||||||
| 		name: 'arguments', |  | ||||||
| 		default: {}, |  | ||||||
| 		description: "The request's query parameters", |  | ||||||
| 		displayOptions: { |  | ||||||
| 			show: { |  | ||||||
| 				resource: ['httpVerb'], |  | ||||||
| 				operation: ['get'], |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		options: [ |  | ||||||
| 			{ |  | ||||||
| 				name: 'keyvalue', |  | ||||||
| 				displayName: 'Key:Value', |  | ||||||
| 				values: [ |  | ||||||
| 					{ |  | ||||||
| 						displayName: 'Key', |  | ||||||
| 						name: 'key', |  | ||||||
| 						type: 'string', |  | ||||||
| 						default: '', |  | ||||||
| 						required: true, |  | ||||||
| 						description: 'Key of query parameter', |  | ||||||
| 					}, |  | ||||||
| 					{ |  | ||||||
| 						displayName: 'Value', |  | ||||||
| 						name: 'value', |  | ||||||
| 						type: 'string', |  | ||||||
| 						default: '', |  | ||||||
| 						routing: { |  | ||||||
| 							send: { |  | ||||||
| 								property: '={{$parent.key}}', |  | ||||||
| 								type: 'query', |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 						required: true, |  | ||||||
| 						description: 'Value of query parameter', |  | ||||||
| 					}, |  | ||||||
| 				], |  | ||||||
| 			}, |  | ||||||
| 		], |  | ||||||
| 		type: 'fixedCollection', |  | ||||||
| 		typeOptions: { |  | ||||||
| 			multipleValues: true, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| ]; |  | ||||||
| 
 |  | ||||||
| // Here we define what to show when the DELETE Operation is selected.
 |  | ||||||
| // We do that by adding `operation: ["delete"]` to `displayOptions.show`
 |  | ||||||
| const deleteOperation: INodeProperties[] = [ |  | ||||||
| 	{ |  | ||||||
| 		displayName: 'Type of Data', |  | ||||||
| 		name: 'typeofData', |  | ||||||
| 		default: 'queryParameter', |  | ||||||
| 		description: 'Select type of data to send [Query Parameter Arguments, JSON-Body]', |  | ||||||
| 		displayOptions: { |  | ||||||
| 			show: { |  | ||||||
| 				resource: ['httpVerb'], |  | ||||||
| 				operation: ['delete'], |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		options: [ |  | ||||||
| 			{ |  | ||||||
| 				name: 'Query', |  | ||||||
| 				value: 'queryParameter', |  | ||||||
| 			}, |  | ||||||
| 			{ |  | ||||||
| 				name: 'JSON', |  | ||||||
| 				value: 'jsonData', |  | ||||||
| 			}, |  | ||||||
| 		], |  | ||||||
| 		required: true, |  | ||||||
| 		type: 'options', |  | ||||||
| 	}, |  | ||||||
| 	{ |  | ||||||
| 		displayName: 'Query Parameters', |  | ||||||
| 		name: 'arguments', |  | ||||||
| 		default: {}, |  | ||||||
| 		description: "The request's query parameters", |  | ||||||
| 		displayOptions: { |  | ||||||
| 			show: { |  | ||||||
| 				resource: ['httpVerb'], |  | ||||||
| 				operation: ['delete'], |  | ||||||
| 				typeofData: ['queryParameter'], |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		options: [ |  | ||||||
| 			{ |  | ||||||
| 				name: 'keyvalue', |  | ||||||
| 				displayName: 'Key:Value', |  | ||||||
| 				values: [ |  | ||||||
| 					{ |  | ||||||
| 						displayName: 'Key', |  | ||||||
| 						name: 'key', |  | ||||||
| 						type: 'string', |  | ||||||
| 						default: '', |  | ||||||
| 						required: true, |  | ||||||
| 						description: 'Key of query parameter', |  | ||||||
| 					}, |  | ||||||
| 					{ |  | ||||||
| 						displayName: 'Value', |  | ||||||
| 						name: 'value', |  | ||||||
| 						type: 'string', |  | ||||||
| 						default: '', |  | ||||||
| 						routing: { |  | ||||||
| 							send: { |  | ||||||
| 								property: '={{$parent.key}}', |  | ||||||
| 								type: 'query', |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 						required: true, |  | ||||||
| 						description: 'Value of query parameter', |  | ||||||
| 					}, |  | ||||||
| 				], |  | ||||||
| 			}, |  | ||||||
| 		], |  | ||||||
| 		type: 'fixedCollection', |  | ||||||
| 		typeOptions: { |  | ||||||
| 			multipleValues: true, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| 	{ |  | ||||||
| 		displayName: 'JSON Object', |  | ||||||
| 		name: 'arguments', |  | ||||||
| 		default: {}, |  | ||||||
| 		description: "The request's JSON properties", |  | ||||||
| 		displayOptions: { |  | ||||||
| 			show: { |  | ||||||
| 				resource: ['httpVerb'], |  | ||||||
| 				operation: ['delete'], |  | ||||||
| 				typeofData: ['jsonData'], |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		options: [ |  | ||||||
| 			{ |  | ||||||
| 				name: 'keyvalue', |  | ||||||
| 				displayName: 'Key:Value', |  | ||||||
| 				values: [ |  | ||||||
| 					{ |  | ||||||
| 						displayName: 'Key', |  | ||||||
| 						name: 'key', |  | ||||||
| 						type: 'string', |  | ||||||
| 						default: '', |  | ||||||
| 						required: true, |  | ||||||
| 						description: 'Key of JSON property', |  | ||||||
| 					}, |  | ||||||
| 					{ |  | ||||||
| 						displayName: 'Value', |  | ||||||
| 						name: 'value', |  | ||||||
| 						type: 'string', |  | ||||||
| 						default: '', |  | ||||||
| 						routing: { |  | ||||||
| 							send: { |  | ||||||
| 								property: '={{$parent.key}}', |  | ||||||
| 								type: 'body', |  | ||||||
| 							}, |  | ||||||
| 						}, |  | ||||||
| 						required: true, |  | ||||||
| 						description: 'Value of JSON property', |  | ||||||
| 					}, |  | ||||||
| 				], |  | ||||||
| 			}, |  | ||||||
| 		], |  | ||||||
| 		type: 'fixedCollection', |  | ||||||
| 		typeOptions: { |  | ||||||
| 			multipleValues: true, |  | ||||||
| 		}, |  | ||||||
| 	}, |  | ||||||
| ]; |  | ||||||
| 
 |  | ||||||
| export const httpVerbFields: INodeProperties[] = [ |  | ||||||
| 	/* -------------------------------------------------------------------------- */ |  | ||||||
| 	/*                                httpVerb:get                                */ |  | ||||||
| 	/* -------------------------------------------------------------------------- */ |  | ||||||
| 	...getOperation, |  | ||||||
| 
 |  | ||||||
| 	/* -------------------------------------------------------------------------- */ |  | ||||||
| 	/*                              httpVerb:delete                               */ |  | ||||||
| 	/* -------------------------------------------------------------------------- */ |  | ||||||
| 	...deleteOperation, |  | ||||||
| ]; |  | ||||||
|  | @ -1,18 +0,0 @@ | ||||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> |  | ||||||
| <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> |  | ||||||
| <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">  <image id="image0" width="32" height="32" x="0" y="0" |  | ||||||
|     href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAABGdBTUEAALGPC/xhBQAAACBjSFJN |  | ||||||
| AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElN |  | ||||||
| RQfmBg4UAC/TqOZZAAACA0lEQVRIx5XVv09TURwF8M+jFHDSyRkGFhPAEfyRdDHi5uriXyDoYgKT |  | ||||||
| MJDWzUT/Ahf/AiOEpajEgCESmpiYmDCxGowDTYE+h76+vte+15Zzk753b7733HNO772PbEw7ECba |  | ||||||
| genswtEcgl0/PHARV72066YrIDSZ6k8KBym4741r0XsB284TdUX8chn1zrzwJUmw4KFXPqjFE0Y0 |  | ||||||
| u5YKEhpmfLZuy7f2wLKGI8WhDRYdaVhurdTCidmU5P44N+skaaGQH1IfFFrOYMotT932zNgQExve |  | ||||||
| OfTeT8dtBceO3TFlOyopY7UPxV+/fWyn3Y0xrFhJjZWFXhs12pKdRO9ObGSuyB8Xbd9JjMjDc6HQ |  | ||||||
| IcrKqAiVe8vyCEJPrGBWxZYqqtZt9RbmHabAvAAVdVUlJTvWshbMt0AYn40OmlchSKOePTyYIMQn |  | ||||||
| rb8yI8TsDCrRs4od7Jv3KOoPGWKboBqp2LN3FQvdO7EPshSsRSTXrSop2cSiiUGkG/bj2JqaQiHW |  | ||||||
| 4nv50mFcu28j30KQarAnEPhuzvwwGYQ975vx7+JwGXTjTIAzoYlhCArR5d0KkfauqJAVY6+FG5hD |  | ||||||
| OS6veqyCuSiTAQT/jKmlQtyxIBCoZV28HQvN6LuQvJFC4xjvibfYOZUdUXd9taTWJbOubiIVXmjG |  | ||||||
| W/fs9qpZcpr6pOe1U0udSf8BR7ef4yxyOskAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjItMDYtMTRU |  | ||||||
| MTc6MDA6NDcrMDM6MDBfo1sRAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIyLTA2LTE0VDE3OjAwOjQ3 |  | ||||||
| KzAzOjAwLv7jrQAAAABJRU5ErkJggg==" /> |  | ||||||
| </svg> |  | ||||||
| Before Width: | Height: | Size: 1.5 KiB | 
							
								
								
									
										20
									
								
								nodes/outgrow/outgrow.node.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								nodes/outgrow/outgrow.node.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | { | ||||||
|  | 	"node": "n8n-nodes-base.outgrow", | ||||||
|  | 	"nodeVersion": "1.0", | ||||||
|  | 	"codexVersion": "1.0", | ||||||
|  | 	"categories": [ | ||||||
|  | 		"Miscellaneous" | ||||||
|  | 	], | ||||||
|  | 	"resources": { | ||||||
|  | 		"credentialDocumentation": [ | ||||||
|  | 			{ | ||||||
|  | 				"url": "" | ||||||
|  | 			} | ||||||
|  | 		], | ||||||
|  | 		"primaryDocumentation": [ | ||||||
|  | 			{ | ||||||
|  | 				"url": "" | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										145
									
								
								nodes/outgrow/outgrow.node.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								nodes/outgrow/outgrow.node.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,145 @@ | ||||||
|  | import { | ||||||
|  | 	ITriggerFunctions, | ||||||
|  | 	INodeType, | ||||||
|  | 	INodeTypeDescription, | ||||||
|  | 	ILoadOptionsFunctions, | ||||||
|  | 	INodePropertyOptions, | ||||||
|  | 	ITriggerResponse, | ||||||
|  | 	NodeApiError, | ||||||
|  | 	NodeConnectionType, | ||||||
|  | } from 'n8n-workflow'; | ||||||
|  | 
 | ||||||
|  | export class outgrow implements INodeType { | ||||||
|  | 	description: INodeTypeDescription = { | ||||||
|  | 		displayName: 'Outgrow Trigger', | ||||||
|  | 		name: 'outgrowTrigger', | ||||||
|  | 		icon: 'file:outgrow.svg', | ||||||
|  | 		group: ['trigger'], | ||||||
|  | 		version: 1, | ||||||
|  | 		subtitle: '={{$parameter["calcId"]}}', | ||||||
|  | 		description: 'Fetch leads from Outgrow calculators at regular intervals', | ||||||
|  | 		defaults: { | ||||||
|  | 			name: 'Outgrow Trigger', | ||||||
|  | 		}, | ||||||
|  | 		inputs: [], | ||||||
|  | 		outputs: [NodeConnectionType.Main], | ||||||
|  | 		credentials: [ | ||||||
|  | 			{ | ||||||
|  | 				name: 'outgrowApi', | ||||||
|  | 				required: true, | ||||||
|  | 			}, | ||||||
|  | 		], | ||||||
|  | 		properties: [ | ||||||
|  | 			{ | ||||||
|  | 				displayName: 'Calculator', | ||||||
|  | 				name: 'calcId', | ||||||
|  | 				type: 'options', | ||||||
|  | 				required: true, | ||||||
|  | 				typeOptions: { | ||||||
|  | 					loadOptionsMethod: 'getCalculators', | ||||||
|  | 				}, | ||||||
|  | 				default: '', | ||||||
|  | 				description: 'Which Outgrow calculator to fetch leads from', | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				displayName: 'Polling Interval (Minutes)', | ||||||
|  | 				name: 'pollingInterval', | ||||||
|  | 				type: 'number', | ||||||
|  | 				required: false, | ||||||
|  | 				default: 5, | ||||||
|  | 				description: 'How often (in minutes) to check for new leads', | ||||||
|  | 			}, | ||||||
|  | 		], | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	methods = { | ||||||
|  | 		loadOptions: { | ||||||
|  | 			async getCalculators(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> { | ||||||
|  | 				const credentials = await this.getCredentials('outgrowApi'); | ||||||
|  | 				if (!credentials?.apiKey) { | ||||||
|  | 					throw new NodeApiError(this.getNode(), { | ||||||
|  | 						message: 'API Key is missing or invalid', | ||||||
|  | 					}); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				const url = `https://api-calc.outgrow.co/api/v1/get_cal/${credentials.apiKey}`; | ||||||
|  | 				try { | ||||||
|  | 					const response = await this.helpers.request({ method: 'GET', url }); | ||||||
|  | 					const calculators = JSON.parse(response); | ||||||
|  | 
 | ||||||
|  | 					return calculators.map((calc: { id: string; calculator: string }) => ({ | ||||||
|  | 						name: calc.calculator, | ||||||
|  | 						value: calc.id, | ||||||
|  | 					})); | ||||||
|  | 				} catch (error) { | ||||||
|  | 					throw new NodeApiError(this.getNode(), error, { | ||||||
|  | 						message: 'Failed to load calculators', | ||||||
|  | 					}); | ||||||
|  | 				} | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	async trigger(this: ITriggerFunctions): Promise<ITriggerResponse> { | ||||||
|  | 		const credentials = await this.getCredentials('outgrowApi'); | ||||||
|  | 		if (!credentials?.apiKey) { | ||||||
|  | 			throw new NodeApiError(this.getNode(), { | ||||||
|  | 				message: 'API Key is missing or invalid', | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		const calcId = this.getNodeParameter('calcId', 0) as string; | ||||||
|  | 		if (!calcId) { | ||||||
|  | 			throw new NodeApiError(this.getNode(), { | ||||||
|  | 				message: 'No calculator selected', | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		const pollingInterval = (this.getNodeParameter('pollingInterval', 0) as number) * 60 * 1000; | ||||||
|  | 		const url = `https://api-calc.outgrow.co/api/v1/get_leads/${credentials.apiKey}/${calcId}`; | ||||||
|  | 
 | ||||||
|  | 		const poll = async () => { | ||||||
|  | 			try { | ||||||
|  | 				const responseData = await this.helpers.request({ | ||||||
|  | 					method: 'GET', | ||||||
|  | 					url, | ||||||
|  | 					json: true, | ||||||
|  | 				}); | ||||||
|  | 
 | ||||||
|  | 				if (responseData?.length > 0) { | ||||||
|  | 					this.emit([this.helpers.returnJsonArray(responseData)]); | ||||||
|  | 				} else { | ||||||
|  | 					// UI-friendly "no leads" response
 | ||||||
|  | 					this.emit([this.helpers.returnJsonArray([{ | ||||||
|  | 						status: 'no_data', | ||||||
|  | 						message: 'No new leads in the last 24 hours', | ||||||
|  | 						calculatorId: calcId, | ||||||
|  | 						timestamp: new Date().toISOString(), | ||||||
|  | 					}])]); | ||||||
|  | 				} | ||||||
|  | 			} catch (error) { | ||||||
|  | 				throw new NodeApiError(this.getNode(), error, { | ||||||
|  | 					message: 'Outgrow API Error', | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		const mode = this.getMode(); | ||||||
|  | 		if (mode === 'manual') { | ||||||
|  | 			return { | ||||||
|  | 				manualTriggerFunction: async () => await poll(), | ||||||
|  | 			}; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (mode === 'trigger') { | ||||||
|  | 			const interval = setInterval(poll, pollingInterval); | ||||||
|  | 			await poll(); // Initial call
 | ||||||
|  | 
 | ||||||
|  | 			return { | ||||||
|  | 				closeFunction: async () => clearInterval(interval), | ||||||
|  | 			}; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return {}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								nodes/outgrow/outgrow.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								nodes/outgrow/outgrow.svg
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| After Width: | Height: | Size: 29 KiB | 
							
								
								
									
										339
									
								
								package.json
									
										
									
									
									
								
							
							
						
						
									
										339
									
								
								package.json
									
										
									
									
									
								
							|  | @ -1,19 +1,16 @@ | ||||||
| { | { | ||||||
|   "name": "n8n-nodes-<...>", |   "name": "n8n-nodes-outgrow", | ||||||
|   "version": "0.1.0", |   "version": "0.1.0", | ||||||
|   "description": "", |   "description": "", | ||||||
|   "keywords": [ |   "keywords": [ | ||||||
|     "n8n-community-node-package" |     "n8n-community-node-package" | ||||||
|   ], |   ], | ||||||
|   "license": "MIT", |   "license": "MIT", | ||||||
|   "homepage": "", |   "homepage": "https://github.com/outgrow/n8n-nodes-outgrow#readme", | ||||||
|   "author": { |   "author": "", | ||||||
|     "name": "", |  | ||||||
|     "email": "" |  | ||||||
|   }, |  | ||||||
|   "repository": { |   "repository": { | ||||||
|     "type": "git", |     "type": "git", | ||||||
|     "url": "https://github.com/<...>/n8n-nodes-<...>.git" |     "url": "git+https://github.com/outgrow/n8n-nodes-outgrow.git" | ||||||
|   }, |   }, | ||||||
|   "engines": { |   "engines": { | ||||||
|     "node": ">=20.15" |     "node": ">=20.15" | ||||||
|  | @ -33,12 +30,10 @@ | ||||||
|   "n8n": { |   "n8n": { | ||||||
|     "n8nNodesApiVersion": 1, |     "n8nNodesApiVersion": 1, | ||||||
|     "credentials": [ |     "credentials": [ | ||||||
|       "dist/credentials/ExampleCredentialsApi.credentials.js", |       "dist/credentials/outgrowApi.credentials.js" | ||||||
|       "dist/credentials/HttpBinApi.credentials.js" |  | ||||||
|     ], |     ], | ||||||
|     "nodes": [ |     "nodes": [ | ||||||
|       "dist/nodes/ExampleNode/ExampleNode.node.js", |       "dist/nodes/outgrow/outgrow.node.js" | ||||||
|       "dist/nodes/HttpBin/HttpBin.node.js" |  | ||||||
|     ] |     ] | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|  | @ -51,5 +46,325 @@ | ||||||
|   }, |   }, | ||||||
|   "peerDependencies": { |   "peerDependencies": { | ||||||
|     "n8n-workflow": "*" |     "n8n-workflow": "*" | ||||||
|  |   }, | ||||||
|  |   "dependencies": { | ||||||
|  |     "acorn": "^8.14.1", | ||||||
|  |     "acorn-jsx": "^5.3.2", | ||||||
|  |     "ajv": "^6.12.6", | ||||||
|  |     "ansi-regex": "^5.0.1", | ||||||
|  |     "ansi-styles": "^4.3.0", | ||||||
|  |     "anymatch": "^3.1.3", | ||||||
|  |     "argparse": "^2.0.1", | ||||||
|  |     "array-each": "^1.0.1", | ||||||
|  |     "array-slice": "^1.1.0", | ||||||
|  |     "array-union": "^2.1.0", | ||||||
|  |     "assert": "^2.1.0", | ||||||
|  |     "ast-types": "^0.15.2", | ||||||
|  |     "async-done": "^2.0.0", | ||||||
|  |     "async-settle": "^2.0.0", | ||||||
|  |     "asynckit": "^0.4.0", | ||||||
|  |     "available-typed-arrays": "^1.0.7", | ||||||
|  |     "axios": "^1.8.2", | ||||||
|  |     "b4a": "^1.6.7", | ||||||
|  |     "bach": "^2.0.1", | ||||||
|  |     "balanced-match": "^1.0.2", | ||||||
|  |     "bare-events": "^2.5.4", | ||||||
|  |     "base64-js": "^1.5.1", | ||||||
|  |     "binary-extensions": "^2.3.0", | ||||||
|  |     "bl": "^5.1.0", | ||||||
|  |     "brace-expansion": "^2.0.1", | ||||||
|  |     "braces": "^3.0.3", | ||||||
|  |     "buffer": "^6.0.3", | ||||||
|  |     "call-bind": "^1.0.8", | ||||||
|  |     "call-bind-apply-helpers": "^1.0.2", | ||||||
|  |     "call-bound": "^1.0.4", | ||||||
|  |     "callsites": "^3.1.0", | ||||||
|  |     "camel-case": "^4.1.2", | ||||||
|  |     "chalk": "^4.1.2", | ||||||
|  |     "charenc": "^0.0.2", | ||||||
|  |     "chokidar": "^3.6.0", | ||||||
|  |     "cliui": "^7.0.4", | ||||||
|  |     "clone": "^2.1.2", | ||||||
|  |     "color-convert": "^2.0.1", | ||||||
|  |     "color-name": "^1.1.4", | ||||||
|  |     "combined-stream": "^1.0.8", | ||||||
|  |     "concat-map": "^0.0.1", | ||||||
|  |     "convert-source-map": "^2.0.0", | ||||||
|  |     "copy-props": "^4.0.0", | ||||||
|  |     "cross-spawn": "^7.0.6", | ||||||
|  |     "crypt": "^0.0.2", | ||||||
|  |     "debug": "^4.4.1", | ||||||
|  |     "deep-equal": "^2.2.0", | ||||||
|  |     "deep-is": "^0.1.4", | ||||||
|  |     "define-data-property": "^1.1.4", | ||||||
|  |     "define-properties": "^1.2.1", | ||||||
|  |     "delayed-stream": "^1.0.0", | ||||||
|  |     "detect-file": "^1.0.0", | ||||||
|  |     "dir-glob": "^3.0.1", | ||||||
|  |     "doctrine": "^3.0.0", | ||||||
|  |     "dunder-proto": "^1.0.1", | ||||||
|  |     "each-props": "^3.0.0", | ||||||
|  |     "emoji-regex": "^8.0.0", | ||||||
|  |     "end-of-stream": "^1.4.4", | ||||||
|  |     "es-define-property": "^1.0.1", | ||||||
|  |     "es-errors": "^1.3.0", | ||||||
|  |     "es-get-iterator": "^1.1.3", | ||||||
|  |     "es-object-atoms": "^1.1.1", | ||||||
|  |     "escalade": "^3.2.0", | ||||||
|  |     "escape-string-regexp": "^4.0.0", | ||||||
|  |     "eslint-config-riot": "^1.0.0", | ||||||
|  |     "eslint-plugin-local": "^1.0.0", | ||||||
|  |     "eslint-scope": "^7.2.2", | ||||||
|  |     "eslint-visitor-keys": "^4.2.0", | ||||||
|  |     "espree": "^9.6.1", | ||||||
|  |     "esprima": "^4.0.1", | ||||||
|  |     "esprima-next": "^5.8.4", | ||||||
|  |     "esquery": "^1.6.0", | ||||||
|  |     "esrecurse": "^4.3.0", | ||||||
|  |     "estraverse": "^5.3.0", | ||||||
|  |     "esutils": "^2.0.3", | ||||||
|  |     "expand-tilde": "^2.0.2", | ||||||
|  |     "extend": "^3.0.2", | ||||||
|  |     "fast-deep-equal": "^3.1.3", | ||||||
|  |     "fast-fifo": "^1.3.2", | ||||||
|  |     "fast-glob": "^3.3.3", | ||||||
|  |     "fast-json-stable-stringify": "^2.1.0", | ||||||
|  |     "fast-levenshtein": "^2.0.6", | ||||||
|  |     "fastest-levenshtein": "^1.0.16", | ||||||
|  |     "fastq": "^1.19.1", | ||||||
|  |     "file-entry-cache": "^6.0.1", | ||||||
|  |     "fill-range": "^7.1.1", | ||||||
|  |     "find-up": "^5.0.0", | ||||||
|  |     "findup-sync": "^5.0.0", | ||||||
|  |     "fined": "^2.0.0", | ||||||
|  |     "flagged-respawn": "^2.0.0", | ||||||
|  |     "flat-cache": "^3.2.0", | ||||||
|  |     "flatted": "^3.3.3", | ||||||
|  |     "follow-redirects": "^1.15.9", | ||||||
|  |     "for-each": "^0.3.5", | ||||||
|  |     "for-in": "^1.0.2", | ||||||
|  |     "for-own": "^1.0.0", | ||||||
|  |     "form-data": "^4.0.0", | ||||||
|  |     "fs-mkdirp-stream": "^2.0.1", | ||||||
|  |     "fs.realpath": "^1.0.0", | ||||||
|  |     "function-bind": "^1.1.2", | ||||||
|  |     "functions-have-names": "^1.2.3", | ||||||
|  |     "get-caller-file": "^2.0.5", | ||||||
|  |     "get-intrinsic": "^1.3.0", | ||||||
|  |     "get-proto": "^1.0.1", | ||||||
|  |     "glob": "^7.2.3", | ||||||
|  |     "glob-parent": "^6.0.2", | ||||||
|  |     "glob-stream": "^8.0.3", | ||||||
|  |     "glob-watcher": "^6.0.0", | ||||||
|  |     "global-modules": "^1.0.0", | ||||||
|  |     "global-prefix": "^1.0.2", | ||||||
|  |     "globals": "^13.24.0", | ||||||
|  |     "globby": "^11.1.0", | ||||||
|  |     "glogg": "^2.2.0", | ||||||
|  |     "gopd": "^1.2.0", | ||||||
|  |     "graceful-fs": "^4.2.11", | ||||||
|  |     "graphemer": "^1.4.0", | ||||||
|  |     "gulp-cli": "^3.1.0", | ||||||
|  |     "gulplog": "^2.2.0", | ||||||
|  |     "has-bigints": "^1.1.0", | ||||||
|  |     "has-flag": "^4.0.0", | ||||||
|  |     "has-property-descriptors": "^1.0.2", | ||||||
|  |     "has-symbols": "^1.1.0", | ||||||
|  |     "has-tostringtag": "^1.0.2", | ||||||
|  |     "hasown": "^2.0.2", | ||||||
|  |     "homedir-polyfill": "^1.0.3", | ||||||
|  |     "iconv-lite": "^0.6.3", | ||||||
|  |     "ieee754": "^1.2.1", | ||||||
|  |     "ignore": "^5.3.2", | ||||||
|  |     "import-fresh": "^3.3.1", | ||||||
|  |     "imurmurhash": "^0.1.4", | ||||||
|  |     "indefinite": "^2.5.1", | ||||||
|  |     "inflight": "^1.0.6", | ||||||
|  |     "inherits": "^2.0.4", | ||||||
|  |     "ini": "^1.3.8", | ||||||
|  |     "internal-slot": "^1.1.0", | ||||||
|  |     "interpret": "^3.1.1", | ||||||
|  |     "is-absolute": "^1.0.0", | ||||||
|  |     "is-arguments": "^1.2.0", | ||||||
|  |     "is-array-buffer": "^3.0.5", | ||||||
|  |     "is-bigint": "^1.1.0", | ||||||
|  |     "is-binary-path": "^2.1.0", | ||||||
|  |     "is-boolean-object": "^1.2.2", | ||||||
|  |     "is-buffer": "^1.1.6", | ||||||
|  |     "is-callable": "^1.2.7", | ||||||
|  |     "is-core-module": "^2.16.1", | ||||||
|  |     "is-date-object": "^1.1.0", | ||||||
|  |     "is-extglob": "^2.1.1", | ||||||
|  |     "is-fullwidth-code-point": "^3.0.0", | ||||||
|  |     "is-generator-function": "^1.1.0", | ||||||
|  |     "is-glob": "^4.0.3", | ||||||
|  |     "is-map": "^2.0.3", | ||||||
|  |     "is-nan": "^1.3.2", | ||||||
|  |     "is-negated-glob": "^1.0.0", | ||||||
|  |     "is-number": "^7.0.0", | ||||||
|  |     "is-number-object": "^1.1.1", | ||||||
|  |     "is-path-inside": "^3.0.3", | ||||||
|  |     "is-plain-object": "^5.0.0", | ||||||
|  |     "is-regex": "^1.2.1", | ||||||
|  |     "is-relative": "^1.0.0", | ||||||
|  |     "is-set": "^2.0.3", | ||||||
|  |     "is-shared-array-buffer": "^1.0.4", | ||||||
|  |     "is-string": "^1.1.1", | ||||||
|  |     "is-symbol": "^1.1.1", | ||||||
|  |     "is-typed-array": "^1.1.15", | ||||||
|  |     "is-unc-path": "^1.0.0", | ||||||
|  |     "is-valid-glob": "^1.0.0", | ||||||
|  |     "is-weakmap": "^2.0.2", | ||||||
|  |     "is-weakset": "^2.0.4", | ||||||
|  |     "is-windows": "^1.0.2", | ||||||
|  |     "isarray": "^2.0.5", | ||||||
|  |     "isexe": "^2.0.0", | ||||||
|  |     "isobject": "^3.0.1", | ||||||
|  |     "jmespath": "^0.16.0", | ||||||
|  |     "js-base64": "^3.7.2", | ||||||
|  |     "js-yaml": "^4.1.0", | ||||||
|  |     "json-buffer": "^3.0.1", | ||||||
|  |     "json-schema-traverse": "^0.4.1", | ||||||
|  |     "json-stable-stringify-without-jsonify": "^1.0.1", | ||||||
|  |     "jssha": "^3.3.1", | ||||||
|  |     "keyv": "^4.5.4", | ||||||
|  |     "last-run": "^2.0.0", | ||||||
|  |     "lead": "^4.0.0", | ||||||
|  |     "levn": "^0.4.1", | ||||||
|  |     "liftoff": "^5.0.1", | ||||||
|  |     "locate-path": "^6.0.0", | ||||||
|  |     "lodash": "^4.17.21", | ||||||
|  |     "lodash.merge": "^4.6.2", | ||||||
|  |     "lower-case": "^2.0.2", | ||||||
|  |     "luxon": "^3.4.4", | ||||||
|  |     "map-cache": "^0.2.2", | ||||||
|  |     "math-intrinsics": "^1.1.0", | ||||||
|  |     "md5": "^2.3.0", | ||||||
|  |     "merge2": "^1.4.1", | ||||||
|  |     "micromatch": "^4.0.8", | ||||||
|  |     "mime-db": "^1.52.0", | ||||||
|  |     "mime-types": "^2.1.35", | ||||||
|  |     "minimatch": "^9.0.5", | ||||||
|  |     "ms": "^2.1.3", | ||||||
|  |     "mute-stdout": "^2.0.0", | ||||||
|  |     "n8n-workflow": "^1.82.0", | ||||||
|  |     "natural-compare": "^1.4.0", | ||||||
|  |     "no-case": "^3.0.4", | ||||||
|  |     "normalize-path": "^3.0.0", | ||||||
|  |     "now-and-later": "^3.0.0", | ||||||
|  |     "object-inspect": "^1.13.4", | ||||||
|  |     "object-is": "^1.1.6", | ||||||
|  |     "object-keys": "^1.1.1", | ||||||
|  |     "object.assign": "^4.1.7", | ||||||
|  |     "object.defaults": "^1.1.0", | ||||||
|  |     "object.pick": "^1.3.0", | ||||||
|  |     "once": "^1.4.0", | ||||||
|  |     "optionator": "^0.9.4", | ||||||
|  |     "p-limit": "^3.1.0", | ||||||
|  |     "p-locate": "^5.0.0", | ||||||
|  |     "parent-module": "^1.0.1", | ||||||
|  |     "parse-filepath": "^1.0.2", | ||||||
|  |     "parse-passwd": "^1.0.0", | ||||||
|  |     "pascal-case": "^3.1.2", | ||||||
|  |     "path-exists": "^4.0.0", | ||||||
|  |     "path-is-absolute": "^1.0.1", | ||||||
|  |     "path-key": "^3.1.1", | ||||||
|  |     "path-parse": "^1.0.7", | ||||||
|  |     "path-root": "^0.1.1", | ||||||
|  |     "path-root-regex": "^0.1.2", | ||||||
|  |     "path-type": "^4.0.0", | ||||||
|  |     "picomatch": "^2.3.1", | ||||||
|  |     "pluralize": "^8.0.0", | ||||||
|  |     "possible-typed-array-names": "^1.1.0", | ||||||
|  |     "prelude-ls": "^1.2.1", | ||||||
|  |     "proxy-from-env": "^1.1.0", | ||||||
|  |     "punycode": "^2.3.1", | ||||||
|  |     "queue-microtask": "^1.2.3", | ||||||
|  |     "readable-stream": "^3.6.2", | ||||||
|  |     "readdirp": "^3.6.0", | ||||||
|  |     "recast": "^0.21.5", | ||||||
|  |     "rechoir": "^0.8.0", | ||||||
|  |     "regexp.prototype.flags": "^1.5.4", | ||||||
|  |     "remove-trailing-separator": "^1.1.0", | ||||||
|  |     "replace-ext": "^2.0.0", | ||||||
|  |     "replace-homedir": "^2.0.0", | ||||||
|  |     "require-directory": "^2.1.1", | ||||||
|  |     "resolve": "^1.22.10", | ||||||
|  |     "resolve-dir": "^1.0.1", | ||||||
|  |     "resolve-from": "^4.0.0", | ||||||
|  |     "resolve-options": "^2.0.0", | ||||||
|  |     "reusify": "^1.1.0", | ||||||
|  |     "rimraf": "^3.0.2", | ||||||
|  |     "run-parallel": "^1.2.0", | ||||||
|  |     "safe-buffer": "^5.2.1", | ||||||
|  |     "safe-regex-test": "^1.1.0", | ||||||
|  |     "safer-buffer": "^2.1.2", | ||||||
|  |     "sax": "^1.4.1", | ||||||
|  |     "semver": "^7.7.2", | ||||||
|  |     "semver-greatest-satisfied-range": "^2.0.0", | ||||||
|  |     "sentence-case": "^3.0.4", | ||||||
|  |     "set-function-length": "^1.2.2", | ||||||
|  |     "set-function-name": "^2.0.2", | ||||||
|  |     "shebang-command": "^2.0.0", | ||||||
|  |     "shebang-regex": "^3.0.0", | ||||||
|  |     "side-channel": "^1.1.0", | ||||||
|  |     "side-channel-list": "^1.0.0", | ||||||
|  |     "side-channel-map": "^1.0.1", | ||||||
|  |     "side-channel-weakmap": "^1.0.2", | ||||||
|  |     "slash": "^3.0.0", | ||||||
|  |     "source-map": "^0.6.1", | ||||||
|  |     "sparkles": "^2.1.0", | ||||||
|  |     "stop-iteration-iterator": "^1.1.0", | ||||||
|  |     "stream-composer": "^1.0.2", | ||||||
|  |     "stream-exhaust": "^1.0.2", | ||||||
|  |     "streamx": "^2.22.1", | ||||||
|  |     "string-width": "^4.2.3", | ||||||
|  |     "string_decoder": "^1.3.0", | ||||||
|  |     "strip-ansi": "^6.0.1", | ||||||
|  |     "strip-json-comments": "^3.1.1", | ||||||
|  |     "supports-color": "^7.2.0", | ||||||
|  |     "supports-preserve-symlinks-flag": "^1.0.0", | ||||||
|  |     "sver": "^1.8.4", | ||||||
|  |     "teex": "^1.0.1", | ||||||
|  |     "text-decoder": "^1.2.3", | ||||||
|  |     "text-table": "^0.2.0", | ||||||
|  |     "title-case": "^3.0.3", | ||||||
|  |     "to-regex-range": "^5.0.1", | ||||||
|  |     "to-through": "^3.0.0", | ||||||
|  |     "transliteration": "^2.3.5", | ||||||
|  |     "ts-api-utils": "^2.1.0", | ||||||
|  |     "tslib": "^2.8.1", | ||||||
|  |     "type-check": "^0.4.0", | ||||||
|  |     "type-fest": "^0.20.2", | ||||||
|  |     "unc-path-regex": "^0.1.2", | ||||||
|  |     "undertaker": "^2.0.0", | ||||||
|  |     "undertaker-registry": "^2.0.0", | ||||||
|  |     "upper-case-first": "^2.0.2", | ||||||
|  |     "uri-js": "^4.4.1", | ||||||
|  |     "util": "^0.12.5", | ||||||
|  |     "util-deprecate": "^1.0.2", | ||||||
|  |     "v8flags": "^4.0.1", | ||||||
|  |     "value-or-function": "^4.0.0", | ||||||
|  |     "vinyl": "^3.0.1", | ||||||
|  |     "vinyl-contents": "^2.0.0", | ||||||
|  |     "vinyl-fs": "^4.0.2", | ||||||
|  |     "vinyl-sourcemap": "^2.0.0", | ||||||
|  |     "which": "^2.0.2", | ||||||
|  |     "which-boxed-primitive": "^1.1.1", | ||||||
|  |     "which-collection": "^1.0.2", | ||||||
|  |     "which-typed-array": "^1.1.19", | ||||||
|  |     "word-wrap": "^1.2.5", | ||||||
|  |     "wrap-ansi": "^7.0.0", | ||||||
|  |     "wrappy": "^1.0.2", | ||||||
|  |     "xml2js": "^0.6.2", | ||||||
|  |     "xmlbuilder": "^11.0.1", | ||||||
|  |     "y18n": "^5.0.8", | ||||||
|  |     "yargs": "^16.2.0", | ||||||
|  |     "yargs-parser": "^20.2.9", | ||||||
|  |     "yocto-queue": "^0.1.0", | ||||||
|  |     "zod": "^3.24.1" | ||||||
|  |   }, | ||||||
|  |   "bugs": { | ||||||
|  |     "url": "https://github.com/outgrow/n8n-nodes-outgrow/issues" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -3,8 +3,8 @@ | ||||||
| 		"strict": true, | 		"strict": true, | ||||||
| 		"module": "commonjs", | 		"module": "commonjs", | ||||||
| 		"moduleResolution": "node", | 		"moduleResolution": "node", | ||||||
| 		"target": "es2019", | 		"target": "ES2020", | ||||||
| 		"lib": ["es2019", "es2020", "es2022.error"], | 		"lib": ["es2019", "es2020", "DOM","es2022.error"], | ||||||
| 		"removeComments": true, | 		"removeComments": true, | ||||||
| 		"useUnknownInCatchVariables": false, | 		"useUnknownInCatchVariables": false, | ||||||
| 		"forceConsistentCasingInFileNames": true, | 		"forceConsistentCasingInFileNames": true, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue