mirror of
				https://github.com/n8n-io/n8n-nodes-starter.git
				synced 2025-10-30 14:52:27 -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 | ||||
| 
 | ||||
| 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) | ||||
| * 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/). | ||||
| ## Installation | ||||
| 
 | ||||
| ## 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. | ||||
| 2. Clone your new repo: | ||||
|    ``` | ||||
|    git clone https://github.com/<your organization>/<your-repo-name>.git | ||||
|    ``` | ||||
| 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. | ||||
| ### Parameters | ||||
| | Field               | Required | Description                                                                 | | ||||
| |---------------------|----------|-----------------------------------------------------------------------------| | ||||
| | **Calculator**      | Yes      | Select which Outgrow calculator to monitor                                  | | ||||
| | **Polling Interval**| No       | Frequency (in minutes) to check for new leads (default: 5)                  | | ||||
| 
 | ||||
| ## 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. | ||||
| 
 | ||||
| ## License | ||||
| 
 | ||||
| [MIT](https://github.com/n8n-io/n8n-nodes-starter/blob/master/LICENSE.md) | ||||
| ### Basic Automation | ||||
| ```json | ||||
| { | ||||
|   "workflow": { | ||||
|     "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", | ||||
|   "description": "", | ||||
|   "description": "", | ||||
|   "keywords": [ | ||||
|     "n8n-community-node-package" | ||||
|   ], | ||||
|   "license": "MIT", | ||||
|   "homepage": "", | ||||
|   "author": { | ||||
|     "name": "", | ||||
|     "email": "" | ||||
|   }, | ||||
|   "homepage": "https://github.com/outgrow/n8n-nodes-outgrow#readme", | ||||
|   "author": "", | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "https://github.com/<...>/n8n-nodes-<...>.git" | ||||
|     "url": "git+https://github.com/outgrow/n8n-nodes-outgrow.git" | ||||
|   }, | ||||
|   "engines": { | ||||
|     "node": ">=20.15" | ||||
|  | @ -33,12 +30,10 @@ | |||
|   "n8n": { | ||||
|     "n8nNodesApiVersion": 1, | ||||
|     "credentials": [ | ||||
|       "dist/credentials/ExampleCredentialsApi.credentials.js", | ||||
|       "dist/credentials/HttpBinApi.credentials.js" | ||||
|       "dist/credentials/outgrowApi.credentials.js" | ||||
|     ], | ||||
|     "nodes": [ | ||||
|       "dist/nodes/ExampleNode/ExampleNode.node.js", | ||||
|       "dist/nodes/HttpBin/HttpBin.node.js" | ||||
|       "dist/nodes/outgrow/outgrow.node.js" | ||||
|     ] | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|  | @ -51,5 +46,325 @@ | |||
|   }, | ||||
|   "peerDependencies": { | ||||
|     "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, | ||||
| 		"module": "commonjs", | ||||
| 		"moduleResolution": "node", | ||||
| 		"target": "es2019", | ||||
| 		"lib": ["es2019", "es2020", "es2022.error"], | ||||
| 		"target": "ES2020", | ||||
| 		"lib": ["es2019", "es2020", "DOM","es2022.error"], | ||||
| 		"removeComments": true, | ||||
| 		"useUnknownInCatchVariables": false, | ||||
| 		"forceConsistentCasingInFileNames": true, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue