@joshuanode/n8n-nodes-scalepad 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +218 -0
- package/dist/credentials/ScalePadCoreApi.credentials.d.ts +9 -0
- package/dist/credentials/ScalePadCoreApi.credentials.js +60 -0
- package/dist/nodes/ScalePadCore/ScalePadCore.node.d.ts +6 -0
- package/dist/nodes/ScalePadCore/ScalePadCore.node.js +344 -0
- package/dist/nodes/ScalePadCore/descriptions/ClientDescription.d.ts +3 -0
- package/dist/nodes/ScalePadCore/descriptions/ClientDescription.js +227 -0
- package/dist/nodes/ScalePadCore/descriptions/ContactDescription.d.ts +3 -0
- package/dist/nodes/ScalePadCore/descriptions/ContactDescription.js +107 -0
- package/dist/nodes/ScalePadCore/descriptions/ContractDescription.d.ts +3 -0
- package/dist/nodes/ScalePadCore/descriptions/ContractDescription.js +121 -0
- package/dist/nodes/ScalePadCore/descriptions/HardwareAssetDescription.d.ts +3 -0
- package/dist/nodes/ScalePadCore/descriptions/HardwareAssetDescription.js +125 -0
- package/dist/nodes/ScalePadCore/descriptions/HardwareLifecycleDescription.d.ts +3 -0
- package/dist/nodes/ScalePadCore/descriptions/HardwareLifecycleDescription.js +142 -0
- package/dist/nodes/ScalePadCore/descriptions/MemberDescription.d.ts +3 -0
- package/dist/nodes/ScalePadCore/descriptions/MemberDescription.js +131 -0
- package/dist/nodes/ScalePadCore/descriptions/OpportunityDescription.d.ts +3 -0
- package/dist/nodes/ScalePadCore/descriptions/OpportunityDescription.js +129 -0
- package/dist/nodes/ScalePadCore/descriptions/SaasDescription.d.ts +3 -0
- package/dist/nodes/ScalePadCore/descriptions/SaasDescription.js +121 -0
- package/dist/nodes/ScalePadCore/descriptions/TicketDescription.d.ts +3 -0
- package/dist/nodes/ScalePadCore/descriptions/TicketDescription.js +146 -0
- package/dist/nodes/ScalePadCore/scalepad.svg +4 -0
- package/dist/nodes/shared/GenericFunctions.d.ts +17 -0
- package/dist/nodes/shared/GenericFunctions.js +101 -0
- package/dist/nodes/shared/types.d.ts +31 -0
- package/dist/nodes/shared/types.js +2 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Joshua Smith
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# n8n-nodes-scalepad
|
|
2
|
+
|
|
3
|
+
This is an n8n community node for **ScalePad Core API** and **Lifecycle Manager**. It provides comprehensive integration with ScalePad's operational and financial insights platform for MSPs.
|
|
4
|
+
|
|
5
|
+
[Installation](#installation) | [Operations](#operations) | [Credentials](#credentials) | [Usage](#usage) | [Resources](#resources)
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation.
|
|
10
|
+
|
|
11
|
+
### Community Nodes (Recommended)
|
|
12
|
+
|
|
13
|
+
1. Go to **Settings > Community Nodes**
|
|
14
|
+
2. Select **Install**
|
|
15
|
+
3. Enter `n8n-nodes-scalepad` in **Enter npm package name**
|
|
16
|
+
4. Agree to the [risks](https://docs.n8n.io/integrations/community-nodes/risks/) of using community nodes
|
|
17
|
+
5. Select **Install**
|
|
18
|
+
|
|
19
|
+
After installation, restart n8n to load the node.
|
|
20
|
+
|
|
21
|
+
### Manual Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install n8n-nodes-scalepad
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Operations
|
|
28
|
+
|
|
29
|
+
This node provides access to the following ScalePad resources:
|
|
30
|
+
|
|
31
|
+
### Resources Available
|
|
32
|
+
|
|
33
|
+
| Resource | Description | Operations |
|
|
34
|
+
|----------|-------------|------------|
|
|
35
|
+
| **Clients** | Client/customer information | Get, Get Many |
|
|
36
|
+
| **Contacts** | Contact details | Get, Get Many |
|
|
37
|
+
| **Contracts** | Contract records | Get, Get Many |
|
|
38
|
+
| **Hardware Assets** | Hardware asset data | Get, Get Many |
|
|
39
|
+
| **Hardware Lifecycle** | Lifecycle tracking, warranties, EOL status | Get, Get Many |
|
|
40
|
+
| **Members** | Team member information | Get, Get Many |
|
|
41
|
+
| **Opportunities** | Sales opportunities | Get, Get Many |
|
|
42
|
+
| **SaaS** | SaaS subscription data | Get, Get Many |
|
|
43
|
+
| **Tickets** | Support ticket records | Get, Get Many |
|
|
44
|
+
|
|
45
|
+
### Operations
|
|
46
|
+
|
|
47
|
+
- **Get** - Retrieve a single record by ID
|
|
48
|
+
- **Get Many** - Retrieve multiple records with filtering, sorting, and pagination
|
|
49
|
+
|
|
50
|
+
### Features
|
|
51
|
+
|
|
52
|
+
✅ **Automatic Pagination** - Handles up to 200 records per request with cursor-based pagination
|
|
53
|
+
✅ **Advanced Filtering** - Filter with operators (eq, ne, contains, gt, lt)
|
|
54
|
+
✅ **Sorting** - Sort results ascending or descending
|
|
55
|
+
✅ **Rate Limit Handling** - Automatic handling of 50 req/5sec limit
|
|
56
|
+
✅ **Comprehensive Error Messages** - Detailed error descriptions and resolutions
|
|
57
|
+
|
|
58
|
+
## Credentials
|
|
59
|
+
|
|
60
|
+
### Authentication: API Key
|
|
61
|
+
|
|
62
|
+
**Requirements:**
|
|
63
|
+
- ScalePad Partner account
|
|
64
|
+
- Administrator permissions
|
|
65
|
+
|
|
66
|
+
**Setup Steps:**
|
|
67
|
+
|
|
68
|
+
1. Sign in to [ScalePad Hub](https://hub.scalepad.com)
|
|
69
|
+
2. Navigate to **API (BETA)** in the top menu
|
|
70
|
+
3. Click **+ Generate** to create a new API key
|
|
71
|
+
4. Enter a descriptive name
|
|
72
|
+
5. Set expiry (default: 2 years)
|
|
73
|
+
6. Copy the API key immediately (won't be shown again)
|
|
74
|
+
|
|
75
|
+
**Configuration in n8n:**
|
|
76
|
+
|
|
77
|
+
- **API Key**: Your generated API key
|
|
78
|
+
- **Environment**:
|
|
79
|
+
- `Production` - https://api.scalepad.com
|
|
80
|
+
- `Sandbox` - https://api-sandbox.scalepad.com
|
|
81
|
+
|
|
82
|
+
## Usage
|
|
83
|
+
|
|
84
|
+
### Example 1: Get All Active Clients
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
Resource: Client
|
|
88
|
+
Operation: Get Many
|
|
89
|
+
Return All: true
|
|
90
|
+
Additional Fields:
|
|
91
|
+
Filter:
|
|
92
|
+
- Field: status
|
|
93
|
+
- Operator: eq
|
|
94
|
+
- Value: active
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Example 2: Monitor Hardware Approaching End of Life
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
Resource: Hardware Lifecycle
|
|
101
|
+
Operation: Get Many
|
|
102
|
+
Return All: true
|
|
103
|
+
Additional Fields:
|
|
104
|
+
EOL Status: approaching_eol
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Example 3: Get Client's Open Tickets
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
Resource: Ticket
|
|
111
|
+
Operation: Get Many
|
|
112
|
+
Return All: false
|
|
113
|
+
Limit: 50
|
|
114
|
+
Additional Fields:
|
|
115
|
+
Client ID: {{$json["client_id"]}}
|
|
116
|
+
Status: open
|
|
117
|
+
Priority: high
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Example 4: List Expiring Warranties
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
Resource: Hardware Lifecycle
|
|
124
|
+
Operation: Get Many
|
|
125
|
+
Return All: true
|
|
126
|
+
Additional Fields:
|
|
127
|
+
Warranty Status: expiring_soon
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## API Limits
|
|
131
|
+
|
|
132
|
+
### Rate Limits
|
|
133
|
+
|
|
134
|
+
- **Limit**: 50 requests per 5 seconds
|
|
135
|
+
- **Automatic Handling**: The node handles rate limit errors with descriptive messages
|
|
136
|
+
- **Best Practice**: Use filters to reduce the number of requests needed
|
|
137
|
+
|
|
138
|
+
### Pagination
|
|
139
|
+
|
|
140
|
+
- **Maximum**: 200 records per request
|
|
141
|
+
- **Type**: Cursor-based pagination
|
|
142
|
+
- **Auto-pagination**: Enable "Return All" to automatically fetch all pages
|
|
143
|
+
|
|
144
|
+
### Performance Tips
|
|
145
|
+
|
|
146
|
+
1. **Use filters** to reduce data transfer
|
|
147
|
+
```
|
|
148
|
+
Additional Fields > Client ID: specific-client-id
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
2. **Limit results** for large datasets
|
|
152
|
+
```
|
|
153
|
+
Return All: false
|
|
154
|
+
Limit: 100
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
3. **Apply sorting** for ordered results
|
|
158
|
+
```
|
|
159
|
+
Sort Field: created_at
|
|
160
|
+
Sort Direction: DESC
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Error Handling
|
|
164
|
+
|
|
165
|
+
The node provides comprehensive error handling:
|
|
166
|
+
|
|
167
|
+
| Error Code | Meaning | Resolution |
|
|
168
|
+
|------------|---------|------------|
|
|
169
|
+
| **401** | Authentication failed | Check API key validity and expiration |
|
|
170
|
+
| **404** | Resource not found | Verify resource ID and access permissions |
|
|
171
|
+
| **429** | Rate limit exceeded | Reduce request frequency or add delays |
|
|
172
|
+
| **500** | Server error | Retry request or contact ScalePad support |
|
|
173
|
+
|
|
174
|
+
All errors include:
|
|
175
|
+
- HTTP status code
|
|
176
|
+
- Error message
|
|
177
|
+
- Detailed description
|
|
178
|
+
- Suggested resolution
|
|
179
|
+
|
|
180
|
+
## API Status
|
|
181
|
+
|
|
182
|
+
**Current Status**: Beta (Read-Only)
|
|
183
|
+
|
|
184
|
+
The ScalePad Core API is currently in beta with read-only access (GET operations only). Full CRUD operations (POST, PATCH, DELETE) will be available in future releases based on partner feedback.
|
|
185
|
+
|
|
186
|
+
## Resources
|
|
187
|
+
|
|
188
|
+
- [ScalePad Core API Documentation](https://developer.scalepad.com/)
|
|
189
|
+
- [ScalePad Community](https://community.scalepad.com/)
|
|
190
|
+
- [n8n Documentation](https://docs.n8n.io/)
|
|
191
|
+
|
|
192
|
+
## Related Packages
|
|
193
|
+
|
|
194
|
+
- [n8n-nodes-quoter](https://www.npmjs.com/package/n8n-nodes-quoter) - Quoter API for quote management
|
|
195
|
+
|
|
196
|
+
## Version History
|
|
197
|
+
|
|
198
|
+
### 0.0.1
|
|
199
|
+
- Initial release
|
|
200
|
+
- ScalePad Core API support (read-only)
|
|
201
|
+
- Lifecycle Manager integration
|
|
202
|
+
- 9 resources with Get and Get Many operations
|
|
203
|
+
- Automatic pagination
|
|
204
|
+
- Advanced filtering and sorting
|
|
205
|
+
- Comprehensive error handling
|
|
206
|
+
|
|
207
|
+
## Support
|
|
208
|
+
|
|
209
|
+
- **GitHub Issues**: [Report a bug](https://github.com/ajoshuasmith/n8n-nodes-scalepad/issues)
|
|
210
|
+
- **ScalePad Community**: [community.scalepad.com](https://community.scalepad.com/)
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
[MIT](LICENSE)
|
|
215
|
+
|
|
216
|
+
## Author
|
|
217
|
+
|
|
218
|
+
ScalePad Community
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class ScalePadCoreApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
authenticate: IAuthenticateGeneric;
|
|
8
|
+
test: ICredentialTestRequest;
|
|
9
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScalePadCoreApi = void 0;
|
|
4
|
+
class ScalePadCoreApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'scalePadCoreApi';
|
|
7
|
+
this.displayName = 'ScalePad Core API';
|
|
8
|
+
this.documentationUrl = 'https://developer.scalepad.com/';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'API Key',
|
|
12
|
+
name: 'apiKey',
|
|
13
|
+
type: 'string',
|
|
14
|
+
typeOptions: {
|
|
15
|
+
password: true,
|
|
16
|
+
},
|
|
17
|
+
default: '',
|
|
18
|
+
required: true,
|
|
19
|
+
description: 'API Key for ScalePad Core API and Lifecycle Manager. Generate from ScalePad Hub > API (BETA).',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
displayName: 'Environment',
|
|
23
|
+
name: 'environment',
|
|
24
|
+
type: 'options',
|
|
25
|
+
options: [
|
|
26
|
+
{
|
|
27
|
+
name: 'Production',
|
|
28
|
+
value: 'production',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'Sandbox',
|
|
32
|
+
value: 'sandbox',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
default: 'production',
|
|
36
|
+
description: 'The environment to connect to',
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
this.authenticate = {
|
|
40
|
+
type: 'generic',
|
|
41
|
+
properties: {
|
|
42
|
+
headers: {
|
|
43
|
+
'x-api-key': '={{$credentials.apiKey}}',
|
|
44
|
+
'Accept': 'application/json',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
this.test = {
|
|
49
|
+
request: {
|
|
50
|
+
baseURL: '={{$credentials.environment === "production" ? "https://api.scalepad.com" : "https://api-sandbox.scalepad.com"}}',
|
|
51
|
+
url: '/core/v1/clients',
|
|
52
|
+
method: 'GET',
|
|
53
|
+
qs: {
|
|
54
|
+
limit: 1,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.ScalePadCoreApi = ScalePadCoreApi;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IExecuteFunctions } from 'n8n-workflow';
|
|
2
|
+
import { INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
3
|
+
export declare class ScalePadCore implements INodeType {
|
|
4
|
+
description: INodeTypeDescription;
|
|
5
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScalePadCore = void 0;
|
|
4
|
+
const GenericFunctions_1 = require("../shared/GenericFunctions");
|
|
5
|
+
const ClientDescription_1 = require("./descriptions/ClientDescription");
|
|
6
|
+
const ContactDescription_1 = require("./descriptions/ContactDescription");
|
|
7
|
+
const ContractDescription_1 = require("./descriptions/ContractDescription");
|
|
8
|
+
const HardwareAssetDescription_1 = require("./descriptions/HardwareAssetDescription");
|
|
9
|
+
const HardwareLifecycleDescription_1 = require("./descriptions/HardwareLifecycleDescription");
|
|
10
|
+
const MemberDescription_1 = require("./descriptions/MemberDescription");
|
|
11
|
+
const OpportunityDescription_1 = require("./descriptions/OpportunityDescription");
|
|
12
|
+
const SaasDescription_1 = require("./descriptions/SaasDescription");
|
|
13
|
+
const TicketDescription_1 = require("./descriptions/TicketDescription");
|
|
14
|
+
class ScalePadCore {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.description = {
|
|
17
|
+
displayName: 'ScalePad Core',
|
|
18
|
+
name: 'scalePadCore',
|
|
19
|
+
icon: 'file:scalepad.svg',
|
|
20
|
+
group: ['transform'],
|
|
21
|
+
version: 1,
|
|
22
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
23
|
+
description: 'Interact with ScalePad Core API and Lifecycle Manager',
|
|
24
|
+
defaults: {
|
|
25
|
+
name: 'ScalePad Core',
|
|
26
|
+
},
|
|
27
|
+
inputs: ['main'],
|
|
28
|
+
outputs: ['main'],
|
|
29
|
+
credentials: [
|
|
30
|
+
{
|
|
31
|
+
name: 'scalePadCoreApi',
|
|
32
|
+
required: true,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
requestDefaults: {
|
|
36
|
+
baseURL: 'https://api.scalepad.com',
|
|
37
|
+
headers: {
|
|
38
|
+
Accept: 'application/json',
|
|
39
|
+
'Content-Type': 'application/json',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
properties: [
|
|
43
|
+
{
|
|
44
|
+
displayName: 'Resource',
|
|
45
|
+
name: 'resource',
|
|
46
|
+
type: 'options',
|
|
47
|
+
noDataExpression: true,
|
|
48
|
+
options: [
|
|
49
|
+
{
|
|
50
|
+
name: 'Client',
|
|
51
|
+
value: 'client',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'Contact',
|
|
55
|
+
value: 'contact',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'Contract',
|
|
59
|
+
value: 'contract',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'Hardware Asset',
|
|
63
|
+
value: 'hardwareAsset',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'Hardware Lifecycle',
|
|
67
|
+
value: 'hardwareLifecycle',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'Member',
|
|
71
|
+
value: 'member',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'Opportunity',
|
|
75
|
+
value: 'opportunity',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'SaaS',
|
|
79
|
+
value: 'saas',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'Ticket',
|
|
83
|
+
value: 'ticket',
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
default: 'client',
|
|
87
|
+
},
|
|
88
|
+
...ClientDescription_1.clientOperations,
|
|
89
|
+
...ClientDescription_1.clientFields,
|
|
90
|
+
...ContactDescription_1.contactOperations,
|
|
91
|
+
...ContactDescription_1.contactFields,
|
|
92
|
+
...ContractDescription_1.contractOperations,
|
|
93
|
+
...ContractDescription_1.contractFields,
|
|
94
|
+
...HardwareAssetDescription_1.hardwareAssetOperations,
|
|
95
|
+
...HardwareAssetDescription_1.hardwareAssetFields,
|
|
96
|
+
...HardwareLifecycleDescription_1.hardwareLifecycleOperations,
|
|
97
|
+
...HardwareLifecycleDescription_1.hardwareLifecycleFields,
|
|
98
|
+
...MemberDescription_1.memberOperations,
|
|
99
|
+
...MemberDescription_1.memberFields,
|
|
100
|
+
...OpportunityDescription_1.opportunityOperations,
|
|
101
|
+
...OpportunityDescription_1.opportunityFields,
|
|
102
|
+
...SaasDescription_1.saasOperations,
|
|
103
|
+
...SaasDescription_1.saasFields,
|
|
104
|
+
...TicketDescription_1.ticketOperations,
|
|
105
|
+
...TicketDescription_1.ticketFields,
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async execute() {
|
|
110
|
+
const items = this.getInputData();
|
|
111
|
+
const returnData = [];
|
|
112
|
+
const resource = this.getNodeParameter('resource', 0);
|
|
113
|
+
const operation = this.getNodeParameter('operation', 0);
|
|
114
|
+
for (let i = 0; i < items.length; i++) {
|
|
115
|
+
try {
|
|
116
|
+
if (resource === 'client') {
|
|
117
|
+
if (operation === 'get') {
|
|
118
|
+
const clientId = this.getNodeParameter('clientId', i);
|
|
119
|
+
const responseData = await GenericFunctions_1.scalePadCoreApiRequest.call(this, 'GET', `/core/v1/clients/${clientId}`);
|
|
120
|
+
returnData.push({ json: responseData });
|
|
121
|
+
}
|
|
122
|
+
if (operation === 'getAll') {
|
|
123
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
124
|
+
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
125
|
+
const qs = {};
|
|
126
|
+
if (!returnAll) {
|
|
127
|
+
qs.limit = this.getNodeParameter('limit', i);
|
|
128
|
+
}
|
|
129
|
+
// Handle filters
|
|
130
|
+
if (additionalFields.filter) {
|
|
131
|
+
const filterData = additionalFields.filter;
|
|
132
|
+
if (filterData.filters && Array.isArray(filterData.filters)) {
|
|
133
|
+
for (const filter of filterData.filters) {
|
|
134
|
+
const field = filter.field;
|
|
135
|
+
const operator = filter.operator;
|
|
136
|
+
const value = filter.value;
|
|
137
|
+
qs[`filter[${field}]`] = `${operator}:${value}`;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Handle sorting
|
|
142
|
+
if (additionalFields.sort) {
|
|
143
|
+
const sortData = additionalFields.sort;
|
|
144
|
+
if (sortData.sortFields) {
|
|
145
|
+
const sortFields = sortData.sortFields;
|
|
146
|
+
const field = sortFields.field;
|
|
147
|
+
const direction = sortFields.direction;
|
|
148
|
+
qs.sort = (0, GenericFunctions_1.buildCoreApiSort)(field, direction);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
let responseData;
|
|
152
|
+
if (returnAll) {
|
|
153
|
+
responseData = await GenericFunctions_1.scalePadCoreApiRequestAllItems.call(this, 'GET', '/core/v1/clients', {}, qs);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const response = await GenericFunctions_1.scalePadCoreApiRequest.call(this, 'GET', '/core/v1/clients', {}, qs);
|
|
157
|
+
responseData = response.data || [];
|
|
158
|
+
}
|
|
159
|
+
responseData.forEach((item) => {
|
|
160
|
+
returnData.push({ json: item });
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (resource === 'contact') {
|
|
165
|
+
if (operation === 'get') {
|
|
166
|
+
const contactId = this.getNodeParameter('contactId', i);
|
|
167
|
+
const responseData = await GenericFunctions_1.scalePadCoreApiRequest.call(this, 'GET', `/core/v1/contacts/${contactId}`);
|
|
168
|
+
returnData.push({ json: responseData });
|
|
169
|
+
}
|
|
170
|
+
if (operation === 'getAll') {
|
|
171
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
172
|
+
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
173
|
+
const qs = {};
|
|
174
|
+
if (!returnAll) {
|
|
175
|
+
qs.limit = this.getNodeParameter('limit', i);
|
|
176
|
+
}
|
|
177
|
+
if (additionalFields.clientId) {
|
|
178
|
+
qs['filter[client_id]'] = `eq:${additionalFields.clientId}`;
|
|
179
|
+
}
|
|
180
|
+
if (additionalFields.email) {
|
|
181
|
+
qs['filter[email]'] = `eq:${additionalFields.email}`;
|
|
182
|
+
}
|
|
183
|
+
let responseData;
|
|
184
|
+
if (returnAll) {
|
|
185
|
+
responseData = await GenericFunctions_1.scalePadCoreApiRequestAllItems.call(this, 'GET', '/core/v1/contacts', {}, qs);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
const response = await GenericFunctions_1.scalePadCoreApiRequest.call(this, 'GET', '/core/v1/contacts', {}, qs);
|
|
189
|
+
responseData = response.data || [];
|
|
190
|
+
}
|
|
191
|
+
responseData.forEach((item) => {
|
|
192
|
+
returnData.push({ json: item });
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (resource === 'ticket') {
|
|
197
|
+
if (operation === 'get') {
|
|
198
|
+
const ticketId = this.getNodeParameter('ticketId', i);
|
|
199
|
+
const responseData = await GenericFunctions_1.scalePadCoreApiRequest.call(this, 'GET', `/core/v1/tickets/${ticketId}`);
|
|
200
|
+
returnData.push({ json: responseData });
|
|
201
|
+
}
|
|
202
|
+
if (operation === 'getAll') {
|
|
203
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
204
|
+
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
205
|
+
const qs = {};
|
|
206
|
+
if (!returnAll) {
|
|
207
|
+
qs.limit = this.getNodeParameter('limit', i);
|
|
208
|
+
}
|
|
209
|
+
if (additionalFields.clientId) {
|
|
210
|
+
qs['filter[client_id]'] = `eq:${additionalFields.clientId}`;
|
|
211
|
+
}
|
|
212
|
+
if (additionalFields.status) {
|
|
213
|
+
qs['filter[status]'] = `eq:${additionalFields.status}`;
|
|
214
|
+
}
|
|
215
|
+
if (additionalFields.priority) {
|
|
216
|
+
qs['filter[priority]'] = `eq:${additionalFields.priority}`;
|
|
217
|
+
}
|
|
218
|
+
let responseData;
|
|
219
|
+
if (returnAll) {
|
|
220
|
+
responseData = await GenericFunctions_1.scalePadCoreApiRequestAllItems.call(this, 'GET', '/core/v1/tickets', {}, qs);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
const response = await GenericFunctions_1.scalePadCoreApiRequest.call(this, 'GET', '/core/v1/tickets', {}, qs);
|
|
224
|
+
responseData = response.data || [];
|
|
225
|
+
}
|
|
226
|
+
responseData.forEach((item) => {
|
|
227
|
+
returnData.push({ json: item });
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
if (resource === 'hardwareLifecycle') {
|
|
232
|
+
if (operation === 'get') {
|
|
233
|
+
const recordId = this.getNodeParameter('recordId', i);
|
|
234
|
+
const responseData = await GenericFunctions_1.scalePadCoreApiRequest.call(this, 'GET', `/core/v1/hardware-lifecycle/${recordId}`);
|
|
235
|
+
returnData.push({ json: responseData });
|
|
236
|
+
}
|
|
237
|
+
if (operation === 'getAll') {
|
|
238
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
239
|
+
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
240
|
+
const qs = {};
|
|
241
|
+
if (!returnAll) {
|
|
242
|
+
qs.limit = this.getNodeParameter('limit', i);
|
|
243
|
+
}
|
|
244
|
+
if (additionalFields.clientId) {
|
|
245
|
+
qs['filter[client_id]'] = `eq:${additionalFields.clientId}`;
|
|
246
|
+
}
|
|
247
|
+
if (additionalFields.warrantyStatus) {
|
|
248
|
+
qs['filter[warranty_status]'] = `eq:${additionalFields.warrantyStatus}`;
|
|
249
|
+
}
|
|
250
|
+
if (additionalFields.eolStatus) {
|
|
251
|
+
qs['filter[eol_status]'] = `eq:${additionalFields.eolStatus}`;
|
|
252
|
+
}
|
|
253
|
+
let responseData;
|
|
254
|
+
if (returnAll) {
|
|
255
|
+
responseData = await GenericFunctions_1.scalePadCoreApiRequestAllItems.call(this, 'GET', '/core/v1/hardware-lifecycle', {}, qs);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
const response = await GenericFunctions_1.scalePadCoreApiRequest.call(this, 'GET', '/core/v1/hardware-lifecycle', {}, qs);
|
|
259
|
+
responseData = response.data || [];
|
|
260
|
+
}
|
|
261
|
+
responseData.forEach((item) => {
|
|
262
|
+
returnData.push({ json: item });
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Similar implementations for other resources
|
|
267
|
+
const resourceMap = {
|
|
268
|
+
contract: 'contracts',
|
|
269
|
+
hardwareAsset: 'hardware-assets',
|
|
270
|
+
member: 'members',
|
|
271
|
+
opportunity: 'opportunities',
|
|
272
|
+
saas: 'saas',
|
|
273
|
+
};
|
|
274
|
+
if (Object.keys(resourceMap).includes(resource)) {
|
|
275
|
+
const endpoint = resourceMap[resource];
|
|
276
|
+
const idParamMap = {
|
|
277
|
+
contract: 'contractId',
|
|
278
|
+
hardwareAsset: 'assetId',
|
|
279
|
+
member: 'memberId',
|
|
280
|
+
opportunity: 'opportunityId',
|
|
281
|
+
saas: 'saasId',
|
|
282
|
+
};
|
|
283
|
+
if (operation === 'get') {
|
|
284
|
+
const id = this.getNodeParameter(idParamMap[resource], i);
|
|
285
|
+
const responseData = await GenericFunctions_1.scalePadCoreApiRequest.call(this, 'GET', `/core/v1/${endpoint}/${id}`);
|
|
286
|
+
returnData.push({ json: responseData });
|
|
287
|
+
}
|
|
288
|
+
if (operation === 'getAll') {
|
|
289
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
290
|
+
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
291
|
+
const qs = {};
|
|
292
|
+
if (!returnAll) {
|
|
293
|
+
qs.limit = this.getNodeParameter('limit', i);
|
|
294
|
+
}
|
|
295
|
+
// Apply common filters
|
|
296
|
+
if (additionalFields.clientId) {
|
|
297
|
+
qs['filter[client_id]'] = `eq:${additionalFields.clientId}`;
|
|
298
|
+
}
|
|
299
|
+
if (additionalFields.status) {
|
|
300
|
+
qs['filter[status]'] = `eq:${additionalFields.status}`;
|
|
301
|
+
}
|
|
302
|
+
// Apply resource-specific filters
|
|
303
|
+
if (resource === 'hardwareAsset' && additionalFields.assetType) {
|
|
304
|
+
qs['filter[asset_type]'] = `eq:${additionalFields.assetType}`;
|
|
305
|
+
}
|
|
306
|
+
if (resource === 'member' && additionalFields.role) {
|
|
307
|
+
qs['filter[role]'] = `eq:${additionalFields.role}`;
|
|
308
|
+
}
|
|
309
|
+
if (resource === 'opportunity' && additionalFields.stage) {
|
|
310
|
+
qs['filter[stage]'] = `eq:${additionalFields.stage}`;
|
|
311
|
+
}
|
|
312
|
+
let responseData;
|
|
313
|
+
if (returnAll) {
|
|
314
|
+
responseData = await GenericFunctions_1.scalePadCoreApiRequestAllItems.call(this, 'GET', `/core/v1/${endpoint}`, {}, qs);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
const response = await GenericFunctions_1.scalePadCoreApiRequest.call(this, 'GET', `/core/v1/${endpoint}`, {}, qs);
|
|
318
|
+
responseData = response.data || [];
|
|
319
|
+
}
|
|
320
|
+
responseData.forEach((item) => {
|
|
321
|
+
returnData.push({ json: item });
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
if (this.continueOnFail()) {
|
|
328
|
+
returnData.push({
|
|
329
|
+
json: {
|
|
330
|
+
error: error.message,
|
|
331
|
+
},
|
|
332
|
+
pairedItem: {
|
|
333
|
+
item: i,
|
|
334
|
+
},
|
|
335
|
+
});
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
throw error;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return [returnData];
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
exports.ScalePadCore = ScalePadCore;
|