mirror of
https://github.com/n8n-io/n8n-nodes-starter.git
synced 2025-10-28 14:12:24 -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 |
341
package.json
341
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