n8n-nodes-confirm8 0.19.0 → 0.21.0
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.
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
2
|
export declare class Confirm8AgentTool implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
|
+
/**
|
|
5
|
+
* Parse natural date queries into filter JSON
|
|
6
|
+
*/
|
|
7
|
+
private parseDateQuery;
|
|
4
8
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
9
|
}
|
|
@@ -10,7 +10,7 @@ class Confirm8AgentTool {
|
|
|
10
10
|
icon: 'file:tool.svg',
|
|
11
11
|
group: ['transform'],
|
|
12
12
|
version: 1,
|
|
13
|
-
description: 'AI
|
|
13
|
+
description: 'AI tool for Confirm8. IMPORTANT: For "OS/ordem de serviço" use resource="order". For dates use filters with start_date/end_date. Example: {"start_date":{"gte":"2025-11-23"},"end_date":{"lte":"2025-11-25"}}',
|
|
14
14
|
defaults: {
|
|
15
15
|
name: 'Confirm8 AI Tool',
|
|
16
16
|
},
|
|
@@ -50,59 +50,132 @@ class Confirm8AgentTool {
|
|
|
50
50
|
default: '',
|
|
51
51
|
required: true,
|
|
52
52
|
},
|
|
53
|
-
// Tool parameters
|
|
53
|
+
// Tool parameters
|
|
54
54
|
{
|
|
55
55
|
displayName: 'Resource',
|
|
56
56
|
name: 'resource',
|
|
57
57
|
type: 'options',
|
|
58
58
|
options: [
|
|
59
|
-
{ name: 'User', value: 'user', description: 'Users/
|
|
60
|
-
{ name: 'Client', value: 'client', description: 'Clients/
|
|
61
|
-
{ name: 'Item', value: 'item', description: 'Items/
|
|
62
|
-
{ name: 'Item Type', value: 'itemType', description: 'Item
|
|
63
|
-
{ name: 'Task', value: 'task', description: 'Tasks/
|
|
64
|
-
{ name: 'Service', value: 'service', description: 'Services' },
|
|
65
|
-
{ name: 'Product', value: 'product', description: 'Products' },
|
|
66
|
-
{ name: 'Order', value: 'order', description: 'Work
|
|
67
|
-
{ name: 'Modality', value: 'modality', description: '
|
|
68
|
-
{ name: 'Ticket', value: 'ticket', description: 'Tickets' },
|
|
69
|
-
{ name: 'Property', value: 'property', description: 'Properties' },
|
|
59
|
+
{ name: 'User', value: 'user', description: 'Users/Employees/Funcionários' },
|
|
60
|
+
{ name: 'Client', value: 'client', description: 'Clients/Customers/Clientes' },
|
|
61
|
+
{ name: 'Item', value: 'item', description: 'Items/Itens' },
|
|
62
|
+
{ name: 'Item Type', value: 'itemType', description: 'Item Types/Tipos' },
|
|
63
|
+
{ name: 'Task', value: 'task', description: 'Tasks/Tarefas/Checklists' },
|
|
64
|
+
{ name: 'Service', value: 'service', description: 'Services/Serviços' },
|
|
65
|
+
{ name: 'Product', value: 'product', description: 'Products/Produtos' },
|
|
66
|
+
{ name: 'Order (OS)', value: 'order', description: 'Work Orders/OS/Ordens de Serviço/WOS' },
|
|
67
|
+
{ name: 'Modality', value: 'modality', description: 'Modalities/Modalidades' },
|
|
68
|
+
{ name: 'Ticket', value: 'ticket', description: 'Tickets/Chamados' },
|
|
69
|
+
{ name: 'Property', value: 'property', description: 'Properties/Propriedades' },
|
|
70
70
|
],
|
|
71
71
|
default: 'user',
|
|
72
|
-
description: '
|
|
72
|
+
description: 'CRITICAL: For "OS" or "ordem de serviço" ALWAYS use "order"',
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
displayName: 'Operation',
|
|
76
76
|
name: 'operation',
|
|
77
77
|
type: 'options',
|
|
78
78
|
options: [
|
|
79
|
-
{ name: 'Get All', value: 'getAll', description: 'List
|
|
80
|
-
{ name: 'Get', value: 'get', description: 'Get
|
|
81
|
-
{ name: 'Create', value: 'create', description: 'Create
|
|
82
|
-
{ name: 'Update', value: 'update', description: 'Update
|
|
83
|
-
{ name: 'Activate', value: 'activate', description: 'Activate
|
|
84
|
-
{ name: 'Deactivate', value: 'deactivate', description: 'Deactivate
|
|
79
|
+
{ name: 'Get All (List)', value: 'getAll', description: 'List/Listar/Buscar todos/Mostrar todos' },
|
|
80
|
+
{ name: 'Get (Single)', value: 'get', description: 'Get one/Buscar um/Obter' },
|
|
81
|
+
{ name: 'Create', value: 'create', description: 'Create/Criar/Adicionar' },
|
|
82
|
+
{ name: 'Update', value: 'update', description: 'Update/Atualizar/Modificar' },
|
|
83
|
+
{ name: 'Activate', value: 'activate', description: 'Activate/Ativar' },
|
|
84
|
+
{ name: 'Deactivate', value: 'deactivate', description: 'Deactivate/Desativar' },
|
|
85
85
|
],
|
|
86
86
|
default: 'getAll',
|
|
87
|
-
description: '
|
|
87
|
+
description: 'CRITICAL: To list/search use "getAll"',
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
displayName: 'Record ID',
|
|
91
91
|
name: 'recordId',
|
|
92
92
|
type: 'string',
|
|
93
93
|
default: '',
|
|
94
|
-
description: 'ID
|
|
94
|
+
description: 'Record ID (only for get/update/activate/deactivate)',
|
|
95
95
|
},
|
|
96
96
|
{
|
|
97
97
|
displayName: 'Data',
|
|
98
98
|
name: 'data',
|
|
99
99
|
type: 'string',
|
|
100
100
|
default: '',
|
|
101
|
-
description: 'JSON data for create/update',
|
|
101
|
+
description: 'JSON data (only for create/update)',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
displayName: 'Filters',
|
|
105
|
+
name: 'filters',
|
|
106
|
+
type: 'string',
|
|
107
|
+
default: '',
|
|
108
|
+
description: 'Filters as JSON. For dates: {"start_date":{"gte":"YYYY-MM-DD"},"end_date":{"lte":"YYYY-MM-DD"}}. For status: {"status":{"eq":"complete"}}',
|
|
102
109
|
},
|
|
103
110
|
],
|
|
104
111
|
};
|
|
105
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Parse natural date queries into filter JSON
|
|
115
|
+
*/
|
|
116
|
+
parseDateQuery(query) {
|
|
117
|
+
const now = new Date();
|
|
118
|
+
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
119
|
+
query = query.toLowerCase().trim();
|
|
120
|
+
// Helper to format date as YYYY-MM-DD
|
|
121
|
+
const formatDate = (date) => {
|
|
122
|
+
return date.toISOString().split('T')[0];
|
|
123
|
+
};
|
|
124
|
+
// Today
|
|
125
|
+
if (query.includes('hoje') || query.includes('today')) {
|
|
126
|
+
const endOfDay = new Date(today);
|
|
127
|
+
endOfDay.setHours(23, 59, 59, 999);
|
|
128
|
+
return {
|
|
129
|
+
start_date: { gte: formatDate(today) },
|
|
130
|
+
end_date: { lte: formatDate(endOfDay) }
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
// This week / semana atual
|
|
134
|
+
if (query.includes('semana') || query.includes('week')) {
|
|
135
|
+
const dayOfWeek = today.getDay();
|
|
136
|
+
const diff = dayOfWeek === 0 ? -6 : 1 - dayOfWeek; // Monday is start
|
|
137
|
+
const weekStart = new Date(today);
|
|
138
|
+
weekStart.setDate(today.getDate() + diff);
|
|
139
|
+
const weekEnd = new Date(weekStart);
|
|
140
|
+
weekEnd.setDate(weekStart.getDate() + 6);
|
|
141
|
+
return {
|
|
142
|
+
start_date: { gte: formatDate(weekStart) },
|
|
143
|
+
end_date: { lte: formatDate(weekEnd) }
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
// This month / mês atual
|
|
147
|
+
if (query.includes('mês') || query.includes('mes') || query.includes('month')) {
|
|
148
|
+
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
149
|
+
const monthEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0);
|
|
150
|
+
return {
|
|
151
|
+
start_date: { gte: formatDate(monthStart) },
|
|
152
|
+
end_date: { lte: formatDate(monthEnd) }
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
// Last N days
|
|
156
|
+
const lastDaysMatch = query.match(/últimos?\s+(\d+)\s+dias?|last\s+(\d+)\s+days?/);
|
|
157
|
+
if (lastDaysMatch) {
|
|
158
|
+
const days = parseInt(lastDaysMatch[1] || lastDaysMatch[2]);
|
|
159
|
+
const startDate = new Date(today);
|
|
160
|
+
startDate.setDate(today.getDate() - days);
|
|
161
|
+
return {
|
|
162
|
+
start_date: { gte: formatDate(startDate) },
|
|
163
|
+
end_date: { lte: formatDate(today) }
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// Next N days
|
|
167
|
+
const nextDaysMatch = query.match(/próximos?\s+(\d+)\s+dias?|next\s+(\d+)\s+days?/);
|
|
168
|
+
if (nextDaysMatch) {
|
|
169
|
+
const days = parseInt(nextDaysMatch[1] || nextDaysMatch[2]);
|
|
170
|
+
const endDate = new Date(today);
|
|
171
|
+
endDate.setDate(today.getDate() + days);
|
|
172
|
+
return {
|
|
173
|
+
start_date: { gte: formatDate(today) },
|
|
174
|
+
end_date: { lte: formatDate(endDate) }
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
106
179
|
async execute() {
|
|
107
180
|
const items = this.getInputData();
|
|
108
181
|
const returnData = [];
|
|
@@ -123,104 +196,233 @@ class Confirm8AgentTool {
|
|
|
123
196
|
data = JSON.parse(dataParam);
|
|
124
197
|
}
|
|
125
198
|
catch (e) {
|
|
126
|
-
// Ignore
|
|
199
|
+
// Ignore
|
|
127
200
|
}
|
|
128
201
|
}
|
|
129
|
-
//
|
|
202
|
+
// Parse filters
|
|
203
|
+
let filters = {};
|
|
204
|
+
const filtersParam = this.getNodeParameter('filters', i, '');
|
|
205
|
+
if (filtersParam) {
|
|
206
|
+
try {
|
|
207
|
+
// Try to parse as JSON first
|
|
208
|
+
filters = JSON.parse(filtersParam);
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
// If not JSON, try to parse as natural language date query
|
|
212
|
+
const parsedDate = this.parseDateQuery(filtersParam);
|
|
213
|
+
if (parsedDate) {
|
|
214
|
+
filters = parsedDate;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Aggressive normalization - EXPAND THIS
|
|
130
219
|
const resourceMap = {
|
|
131
|
-
|
|
220
|
+
// Standard
|
|
221
|
+
'users': 'user', 'usuarios': 'user', 'usuários': 'user', 'employees': 'user', 'funcionários': 'user', 'funcionarios': 'user',
|
|
132
222
|
'clients': 'client', 'clientes': 'client', 'customers': 'client',
|
|
133
223
|
'items': 'item', 'itens': 'item',
|
|
134
224
|
'itemtypes': 'itemType', 'tipos': 'itemType',
|
|
135
225
|
'tasks': 'task', 'tarefas': 'task',
|
|
136
226
|
'services': 'service', 'serviços': 'service', 'servicos': 'service',
|
|
137
227
|
'products': 'product', 'produtos': 'product',
|
|
138
|
-
'orders': 'order', 'ordens': 'order', 'pedidos': 'order', 'wos': 'order',
|
|
139
228
|
'modalities': 'modality', 'modalidades': 'modality',
|
|
140
229
|
'tickets': 'ticket', 'chamados': 'ticket',
|
|
141
230
|
'properties': 'property', 'propriedades': 'property',
|
|
231
|
+
// CRITICAL: OS mappings
|
|
232
|
+
'os': 'order',
|
|
233
|
+
'o.s': 'order',
|
|
234
|
+
'o.s.': 'order',
|
|
235
|
+
'orders': 'order',
|
|
236
|
+
'ordens': 'order',
|
|
237
|
+
'ordem': 'order',
|
|
238
|
+
'ordem de serviço': 'order',
|
|
239
|
+
'ordem de servico': 'order',
|
|
240
|
+
'ordens de serviço': 'order',
|
|
241
|
+
'ordens de servico': 'order',
|
|
242
|
+
'wos': 'order',
|
|
243
|
+
'work order': 'order',
|
|
244
|
+
'work orders': 'order',
|
|
245
|
+
'pedidos': 'order',
|
|
246
|
+
'pedido': 'order',
|
|
142
247
|
};
|
|
143
248
|
const operationMap = {
|
|
144
|
-
|
|
145
|
-
'
|
|
146
|
-
'
|
|
147
|
-
'
|
|
148
|
-
'
|
|
149
|
-
'
|
|
150
|
-
'
|
|
151
|
-
'
|
|
249
|
+
// List/Get All
|
|
250
|
+
'list': 'getAll',
|
|
251
|
+
'listar': 'getAll',
|
|
252
|
+
'mostrar': 'getAll',
|
|
253
|
+
'buscar': 'getAll',
|
|
254
|
+
'busque': 'getAll',
|
|
255
|
+
'buscar todos': 'getAll',
|
|
256
|
+
'buscar todas': 'getAll',
|
|
257
|
+
'buscar todo': 'getAll',
|
|
258
|
+
'buscar toda': 'getAll',
|
|
259
|
+
'get all': 'getAll',
|
|
260
|
+
'show all': 'getAll',
|
|
261
|
+
'list all': 'getAll',
|
|
262
|
+
'todos': 'getAll',
|
|
263
|
+
'todas': 'getAll',
|
|
264
|
+
'obter todos': 'getAll',
|
|
265
|
+
'obter todas': 'getAll',
|
|
266
|
+
'pegar todos': 'getAll',
|
|
267
|
+
'pegar todas': 'getAll',
|
|
268
|
+
// Get Single
|
|
269
|
+
'obter': 'get',
|
|
270
|
+
'pegar': 'get',
|
|
271
|
+
'ver': 'get',
|
|
272
|
+
'visualizar': 'get',
|
|
273
|
+
// Create
|
|
274
|
+
'criar': 'create',
|
|
275
|
+
'adicionar': 'create',
|
|
276
|
+
'add': 'create',
|
|
277
|
+
'novo': 'create',
|
|
278
|
+
'nova': 'create',
|
|
279
|
+
'new': 'create',
|
|
280
|
+
// Update
|
|
281
|
+
'atualizar': 'update',
|
|
282
|
+
'modificar': 'update',
|
|
283
|
+
'modify': 'update',
|
|
284
|
+
'editar': 'update',
|
|
285
|
+
'edit': 'update',
|
|
286
|
+
// Activate/Deactivate
|
|
287
|
+
'ativar': 'activate',
|
|
288
|
+
'enable': 'activate',
|
|
289
|
+
'habilitar': 'activate',
|
|
290
|
+
'desativar': 'deactivate',
|
|
291
|
+
'disable': 'deactivate',
|
|
292
|
+
'desabilitar': 'deactivate',
|
|
152
293
|
};
|
|
153
|
-
// Normalize
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
294
|
+
// Normalize - clean and map
|
|
295
|
+
const cleanResource = resource.toLowerCase().trim().replace(/\s+/g, ' ');
|
|
296
|
+
const cleanOperation = operation.toLowerCase().trim().replace(/\s+/g, ' ');
|
|
297
|
+
resource = resourceMap[cleanResource] || resource;
|
|
298
|
+
operation = operationMap[cleanOperation] || operation;
|
|
299
|
+
// If still not valid, throw clear error
|
|
300
|
+
const validResources = ['user', 'client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality', 'ticket', 'property'];
|
|
301
|
+
const validOperations = ['getAll', 'get', 'create', 'update', 'activate', 'deactivate'];
|
|
302
|
+
if (!validResources.includes(resource)) {
|
|
303
|
+
throw new Error(`Invalid resource: "${resource}". Must be one of: ${validResources.join(', ')}. ` +
|
|
304
|
+
`For OS/Ordem de Serviço use "order".`);
|
|
158
305
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
client: 'clients',
|
|
163
|
-
item: 'items',
|
|
164
|
-
itemType: 'itemTypes',
|
|
165
|
-
task: 'tasks',
|
|
166
|
-
service: 'services',
|
|
167
|
-
product: 'products',
|
|
168
|
-
order: 'wos',
|
|
169
|
-
modality: 'modalities',
|
|
170
|
-
ticket: 'tickets',
|
|
171
|
-
property: 'properties',
|
|
172
|
-
};
|
|
173
|
-
const baseEndpoint = endpointMap[resource];
|
|
174
|
-
if (!baseEndpoint) {
|
|
175
|
-
throw new Error(`Unknown resource: ${resource}. Must be one of: user, client, item, itemType, task, service, product, order, modality, ticket, property`);
|
|
306
|
+
if (!validOperations.includes(operation)) {
|
|
307
|
+
throw new Error(`Invalid operation: "${operation}". Must be one of: ${validOperations.join(', ')}. ` +
|
|
308
|
+
`To list/search use "getAll".`);
|
|
176
309
|
}
|
|
310
|
+
// Resource config with relations
|
|
311
|
+
const resourceConfig = {
|
|
312
|
+
user: {
|
|
313
|
+
endpoint: 'users',
|
|
314
|
+
relations: ['clients', 'attachments', 'permissions', 'device', 'employee']
|
|
315
|
+
},
|
|
316
|
+
client: {
|
|
317
|
+
endpoint: 'clients',
|
|
318
|
+
relations: ['wos', 'items', 'employees', 'headquarter', 'files', 'userGroup', 'properties']
|
|
319
|
+
},
|
|
320
|
+
item: {
|
|
321
|
+
endpoint: 'items',
|
|
322
|
+
relations: ['client', 'item_type', 'properties', 'parent', 'children', 'collects', 'wos']
|
|
323
|
+
},
|
|
324
|
+
itemType: {
|
|
325
|
+
endpoint: 'itemTypes',
|
|
326
|
+
relations: ['properties']
|
|
327
|
+
},
|
|
328
|
+
task: {
|
|
329
|
+
endpoint: 'tasks',
|
|
330
|
+
relations: ['itemType', 'activities', 'wos', 'modalities']
|
|
331
|
+
},
|
|
332
|
+
service: {
|
|
333
|
+
endpoint: 'services',
|
|
334
|
+
relations: ['task']
|
|
335
|
+
},
|
|
336
|
+
product: {
|
|
337
|
+
endpoint: 'products',
|
|
338
|
+
relations: []
|
|
339
|
+
},
|
|
340
|
+
order: {
|
|
341
|
+
endpoint: 'wos',
|
|
342
|
+
relations: ['client', 'modalities', 'tasks', 'pivot_tasks', 'products', 'users', 'items', 'tickets', 'services', 'collects', 'attachments']
|
|
343
|
+
},
|
|
344
|
+
modality: {
|
|
345
|
+
endpoint: 'modalities',
|
|
346
|
+
relations: ['tasks']
|
|
347
|
+
},
|
|
348
|
+
ticket: {
|
|
349
|
+
endpoint: 'tickets',
|
|
350
|
+
relations: ['client', 'subject_category', 'category', 'status', 'attachments', 'item', 'owner', 'priority', 'users', 'orders', 'properties']
|
|
351
|
+
},
|
|
352
|
+
property: {
|
|
353
|
+
endpoint: 'properties',
|
|
354
|
+
relations: []
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
const config = resourceConfig[resource];
|
|
358
|
+
const baseEndpoint = config.endpoint;
|
|
177
359
|
let endpoint = '';
|
|
178
360
|
let method = 'GET';
|
|
179
361
|
let body = {};
|
|
180
|
-
// Build
|
|
362
|
+
// Build endpoint
|
|
181
363
|
switch (operation) {
|
|
182
364
|
case 'getAll':
|
|
183
|
-
endpoint =
|
|
365
|
+
endpoint = `/v3/${baseEndpoint}`;
|
|
184
366
|
break;
|
|
185
367
|
case 'get':
|
|
186
368
|
if (!recordId)
|
|
187
|
-
throw new Error('recordId required
|
|
188
|
-
endpoint =
|
|
369
|
+
throw new Error('recordId required');
|
|
370
|
+
endpoint = `/v3/${baseEndpoint}/${recordId}`;
|
|
189
371
|
break;
|
|
190
372
|
case 'create':
|
|
191
|
-
endpoint =
|
|
373
|
+
endpoint = `/v3/${baseEndpoint}`;
|
|
192
374
|
method = 'POST';
|
|
193
375
|
body = data;
|
|
194
376
|
break;
|
|
195
377
|
case 'update':
|
|
196
378
|
if (!recordId)
|
|
197
|
-
throw new Error('recordId required
|
|
198
|
-
endpoint =
|
|
379
|
+
throw new Error('recordId required');
|
|
380
|
+
endpoint = `/v3/${baseEndpoint}/${recordId}`;
|
|
199
381
|
method = 'PUT';
|
|
200
382
|
body = data;
|
|
201
383
|
break;
|
|
202
384
|
case 'activate':
|
|
203
385
|
if (!recordId)
|
|
204
|
-
throw new Error('recordId required
|
|
205
|
-
endpoint =
|
|
386
|
+
throw new Error('recordId required');
|
|
387
|
+
endpoint = `/v3/${baseEndpoint}/${recordId}/active`;
|
|
206
388
|
method = ['client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality'].includes(resource)
|
|
207
389
|
? 'PUT' : 'PATCH';
|
|
208
390
|
break;
|
|
209
391
|
case 'deactivate':
|
|
210
392
|
if (!recordId)
|
|
211
|
-
throw new Error('recordId required
|
|
212
|
-
endpoint =
|
|
393
|
+
throw new Error('recordId required');
|
|
394
|
+
endpoint = `/v3/${baseEndpoint}/${recordId}/inactive`;
|
|
213
395
|
method = ['client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality'].includes(resource)
|
|
214
396
|
? 'PUT' : 'PATCH';
|
|
215
397
|
break;
|
|
216
|
-
|
|
217
|
-
|
|
398
|
+
}
|
|
399
|
+
// Build query string
|
|
400
|
+
const queryParams = [];
|
|
401
|
+
// Add relations (only GET)
|
|
402
|
+
if (method === 'GET' && config.relations.length > 0) {
|
|
403
|
+
config.relations.forEach(relation => {
|
|
404
|
+
queryParams.push(`relations=${relation}`);
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
// Add filters
|
|
408
|
+
if (Object.keys(filters).length > 0) {
|
|
409
|
+
Object.keys(filters).forEach(field => {
|
|
410
|
+
const operators = filters[field];
|
|
411
|
+
Object.keys(operators).forEach(operator => {
|
|
412
|
+
const value = operators[operator];
|
|
413
|
+
queryParams.push(`filters[${field}][${operator}]=${encodeURIComponent(String(value))}`);
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
// Full URL
|
|
418
|
+
let fullUrl = `${baseUrl}${endpoint}`;
|
|
419
|
+
if (queryParams.length > 0) {
|
|
420
|
+
fullUrl += '?' + queryParams.join('&');
|
|
218
421
|
}
|
|
219
422
|
// Make request
|
|
220
|
-
const url = `${baseUrl}${endpoint}`;
|
|
221
423
|
const options = {
|
|
222
424
|
method,
|
|
223
|
-
uri:
|
|
425
|
+
uri: fullUrl,
|
|
224
426
|
headers: {
|
|
225
427
|
'Authorization': `Bearer ${bearerToken}`,
|
|
226
428
|
'X-API-DOMAIN': apiDomain,
|
|
@@ -236,15 +438,18 @@ class Confirm8AgentTool {
|
|
|
236
438
|
returnData.push({
|
|
237
439
|
json: {
|
|
238
440
|
success: true,
|
|
239
|
-
operation,
|
|
240
|
-
resource,
|
|
241
441
|
normalized: {
|
|
242
442
|
originalResource: this.getNodeParameter('resource', i, ''),
|
|
243
443
|
originalOperation: this.getNodeParameter('operation', i, ''),
|
|
244
444
|
normalizedResource: resource,
|
|
245
445
|
normalizedOperation: operation,
|
|
246
446
|
},
|
|
447
|
+
operation,
|
|
448
|
+
resource,
|
|
247
449
|
endpoint,
|
|
450
|
+
fullUrl,
|
|
451
|
+
relations: config.relations,
|
|
452
|
+
filters: filters,
|
|
248
453
|
method,
|
|
249
454
|
data: responseData,
|
|
250
455
|
},
|