@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.
Files changed (30) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +218 -0
  3. package/dist/credentials/ScalePadCoreApi.credentials.d.ts +9 -0
  4. package/dist/credentials/ScalePadCoreApi.credentials.js +60 -0
  5. package/dist/nodes/ScalePadCore/ScalePadCore.node.d.ts +6 -0
  6. package/dist/nodes/ScalePadCore/ScalePadCore.node.js +344 -0
  7. package/dist/nodes/ScalePadCore/descriptions/ClientDescription.d.ts +3 -0
  8. package/dist/nodes/ScalePadCore/descriptions/ClientDescription.js +227 -0
  9. package/dist/nodes/ScalePadCore/descriptions/ContactDescription.d.ts +3 -0
  10. package/dist/nodes/ScalePadCore/descriptions/ContactDescription.js +107 -0
  11. package/dist/nodes/ScalePadCore/descriptions/ContractDescription.d.ts +3 -0
  12. package/dist/nodes/ScalePadCore/descriptions/ContractDescription.js +121 -0
  13. package/dist/nodes/ScalePadCore/descriptions/HardwareAssetDescription.d.ts +3 -0
  14. package/dist/nodes/ScalePadCore/descriptions/HardwareAssetDescription.js +125 -0
  15. package/dist/nodes/ScalePadCore/descriptions/HardwareLifecycleDescription.d.ts +3 -0
  16. package/dist/nodes/ScalePadCore/descriptions/HardwareLifecycleDescription.js +142 -0
  17. package/dist/nodes/ScalePadCore/descriptions/MemberDescription.d.ts +3 -0
  18. package/dist/nodes/ScalePadCore/descriptions/MemberDescription.js +131 -0
  19. package/dist/nodes/ScalePadCore/descriptions/OpportunityDescription.d.ts +3 -0
  20. package/dist/nodes/ScalePadCore/descriptions/OpportunityDescription.js +129 -0
  21. package/dist/nodes/ScalePadCore/descriptions/SaasDescription.d.ts +3 -0
  22. package/dist/nodes/ScalePadCore/descriptions/SaasDescription.js +121 -0
  23. package/dist/nodes/ScalePadCore/descriptions/TicketDescription.d.ts +3 -0
  24. package/dist/nodes/ScalePadCore/descriptions/TicketDescription.js +146 -0
  25. package/dist/nodes/ScalePadCore/scalepad.svg +4 -0
  26. package/dist/nodes/shared/GenericFunctions.d.ts +17 -0
  27. package/dist/nodes/shared/GenericFunctions.js +101 -0
  28. package/dist/nodes/shared/types.d.ts +31 -0
  29. package/dist/nodes/shared/types.js +2 -0
  30. 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;
@@ -0,0 +1,3 @@
1
+ import { INodeProperties } from 'n8n-workflow';
2
+ export declare const clientOperations: INodeProperties[];
3
+ export declare const clientFields: INodeProperties[];