n8n-nodes-confirm8 0.21.0 → 0.22.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,4 +1,4 @@
1
- import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from "n8n-workflow";
2
2
  export declare class Confirm8AgentTool implements INodeType {
3
3
  description: INodeTypeDescription;
4
4
  /**
@@ -2,109 +2,204 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Confirm8AgentTool = void 0;
4
4
  const n8n_workflow_1 = require("n8n-workflow");
5
+ // -----------------------------------------------------------------------------
6
+ // STRICT ALLOWED VALUES (used both for UI + for agent/tool schema guidance)
7
+ // IMPORTANT: Any agent calling this tool MUST use ONLY these exact tokens.
8
+ // -----------------------------------------------------------------------------
9
+ const VALID_RESOURCES = [
10
+ "user",
11
+ "client",
12
+ "item",
13
+ "itemType",
14
+ "task",
15
+ "service",
16
+ "product",
17
+ "order",
18
+ "modality",
19
+ "ticket",
20
+ "property",
21
+ ];
22
+ const VALID_OPERATIONS = [
23
+ "getAll",
24
+ "get",
25
+ "create",
26
+ "update",
27
+ "activate",
28
+ "deactivate",
29
+ ];
30
+ const AGENT_USAGE_NOTE = `
31
+ CRITICAL (Agents):
32
+ - You MUST return ONLY the option *value* token (not the label).
33
+ - Allowed resource values: ${VALID_RESOURCES.join(", ")}
34
+ - Allowed operation values: ${VALID_OPERATIONS.join(", ")}
35
+ Examples:
36
+ - "Ordem de Serviço" / "OS" / "Work Order" => resource="order"
37
+ - To list/search => operation="getAll"
38
+ Anything outside these lists will throw a fatal error.
39
+ `.trim();
5
40
  class Confirm8AgentTool {
6
41
  constructor() {
7
42
  this.description = {
8
- displayName: 'Confirm8 AI Tool',
9
- name: 'confirm8AgentTool',
10
- icon: 'file:tool.svg',
11
- group: ['transform'],
43
+ displayName: "Confirm8 AI Tool",
44
+ name: "confirm8AgentTool",
45
+ icon: "file:tool.svg",
46
+ group: ["transform"],
12
47
  version: 1,
13
48
  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
49
  defaults: {
15
- name: 'Confirm8 AI Tool',
50
+ name: "Confirm8 AI Tool",
16
51
  },
17
52
  usableAsTool: true,
18
- inputs: ['main'],
19
- outputs: ['main'],
53
+ inputs: ["main"],
54
+ outputs: ["main"],
20
55
  properties: [
21
56
  // API Configuration
22
57
  {
23
- displayName: 'Base URL',
24
- name: 'baseUrl',
25
- type: 'string',
26
- default: '',
27
- placeholder: 'https://api.confirm8.com',
58
+ displayName: "Base URL",
59
+ name: "baseUrl",
60
+ type: "string",
61
+ default: "",
62
+ placeholder: "https://api.confirm8.com",
28
63
  required: true,
29
64
  },
30
65
  {
31
- displayName: 'Bearer Token',
32
- name: 'bearerToken',
33
- type: 'string',
66
+ displayName: "Bearer Token",
67
+ name: "bearerToken",
68
+ type: "string",
34
69
  typeOptions: { password: true },
35
- default: '',
70
+ default: "",
36
71
  required: true,
37
72
  },
38
73
  {
39
- displayName: 'X-API-DOMAIN',
40
- name: 'apiDomain',
41
- type: 'string',
42
- default: '',
74
+ displayName: "X-API-DOMAIN",
75
+ name: "apiDomain",
76
+ type: "string",
77
+ default: "",
43
78
  required: true,
44
79
  },
45
80
  {
46
- displayName: 'X-APIKEY-TOKEN',
47
- name: 'apiKeyToken',
48
- type: 'string',
81
+ displayName: "X-APIKEY-TOKEN",
82
+ name: "apiKeyToken",
83
+ type: "string",
49
84
  typeOptions: { password: true },
50
- default: '',
85
+ default: "",
51
86
  required: true,
52
87
  },
53
88
  // Tool parameters
54
89
  {
55
- displayName: 'Resource',
56
- name: 'resource',
57
- type: 'options',
90
+ displayName: "Resource",
91
+ name: "resource",
92
+ type: "options",
58
93
  options: [
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' },
94
+ {
95
+ name: "User",
96
+ value: "user",
97
+ description: "Users/Employees/Funcionários",
98
+ },
99
+ {
100
+ name: "Client",
101
+ value: "client",
102
+ description: "Clients/Customers/Clientes",
103
+ },
104
+ { name: "Item", value: "item", description: "Items/Itens" },
105
+ {
106
+ name: "Item Type",
107
+ value: "itemType",
108
+ description: "Item Types/Tipos",
109
+ },
110
+ {
111
+ name: "Task",
112
+ value: "task",
113
+ description: "Tasks/Tarefas/Checklists",
114
+ },
115
+ {
116
+ name: "Service",
117
+ value: "service",
118
+ description: "Services/Serviços",
119
+ },
120
+ {
121
+ name: "Product",
122
+ value: "product",
123
+ description: "Products/Produtos",
124
+ },
125
+ {
126
+ name: "Order (OS)",
127
+ value: "order",
128
+ description: "Work Orders/OS/Ordens de Serviço/WOS",
129
+ },
130
+ {
131
+ name: "Modality",
132
+ value: "modality",
133
+ description: "Modalities/Modalidades",
134
+ },
135
+ { name: "Ticket", value: "ticket", description: "Tickets/Chamados" },
136
+ {
137
+ name: "Property",
138
+ value: "property",
139
+ description: "Properties/Propriedades",
140
+ },
70
141
  ],
71
- default: 'user',
72
- description: 'CRITICAL: For "OS" or "ordem de serviço" ALWAYS use "order"',
142
+ default: "user",
143
+ description: AGENT_USAGE_NOTE,
73
144
  },
74
145
  {
75
- displayName: 'Operation',
76
- name: 'operation',
77
- type: 'options',
146
+ displayName: "Operation",
147
+ name: "operation",
148
+ type: "options",
78
149
  options: [
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' },
150
+ {
151
+ name: "Get All (List)",
152
+ value: "getAll",
153
+ description: AGENT_USAGE_NOTE,
154
+ },
155
+ {
156
+ name: "Get (Single)",
157
+ value: "get",
158
+ description: AGENT_USAGE_NOTE,
159
+ },
160
+ {
161
+ name: "Create",
162
+ value: "create",
163
+ description: AGENT_USAGE_NOTE,
164
+ },
165
+ {
166
+ name: "Update",
167
+ value: "update",
168
+ description: AGENT_USAGE_NOTE,
169
+ },
170
+ {
171
+ name: "Activate",
172
+ value: "activate",
173
+ description: AGENT_USAGE_NOTE,
174
+ },
175
+ {
176
+ name: "Deactivate",
177
+ value: "deactivate",
178
+ description: AGENT_USAGE_NOTE,
179
+ },
85
180
  ],
86
- default: 'getAll',
87
- description: 'CRITICAL: To list/search use "getAll"',
181
+ default: "getAll",
182
+ description: AGENT_USAGE_NOTE,
88
183
  },
89
184
  {
90
- displayName: 'Record ID',
91
- name: 'recordId',
92
- type: 'string',
93
- default: '',
94
- description: 'Record ID (only for get/update/activate/deactivate)',
185
+ displayName: "Record ID",
186
+ name: "recordId",
187
+ type: "string",
188
+ default: "",
189
+ description: "Record ID (only for get/update/activate/deactivate)",
95
190
  },
96
191
  {
97
- displayName: 'Data',
98
- name: 'data',
99
- type: 'string',
100
- default: '',
101
- description: 'JSON data (only for create/update)',
192
+ displayName: "Data",
193
+ name: "data",
194
+ type: "string",
195
+ default: "",
196
+ description: "JSON data (only for create/update)",
102
197
  },
103
198
  {
104
- displayName: 'Filters',
105
- name: 'filters',
106
- type: 'string',
107
- default: '',
199
+ displayName: "Filters",
200
+ name: "filters",
201
+ type: "string",
202
+ default: "",
108
203
  description: 'Filters as JSON. For dates: {"start_date":{"gte":"YYYY-MM-DD"},"end_date":{"lte":"YYYY-MM-DD"}}. For status: {"status":{"eq":"complete"}}',
109
204
  },
110
205
  ],
@@ -119,19 +214,19 @@ class Confirm8AgentTool {
119
214
  query = query.toLowerCase().trim();
120
215
  // Helper to format date as YYYY-MM-DD
121
216
  const formatDate = (date) => {
122
- return date.toISOString().split('T')[0];
217
+ return date.toISOString().split("T")[0];
123
218
  };
124
219
  // Today
125
- if (query.includes('hoje') || query.includes('today')) {
220
+ if (query.includes("hoje") || query.includes("today")) {
126
221
  const endOfDay = new Date(today);
127
222
  endOfDay.setHours(23, 59, 59, 999);
128
223
  return {
129
224
  start_date: { gte: formatDate(today) },
130
- end_date: { lte: formatDate(endOfDay) }
225
+ end_date: { lte: formatDate(endOfDay) },
131
226
  };
132
227
  }
133
228
  // This week / semana atual
134
- if (query.includes('semana') || query.includes('week')) {
229
+ if (query.includes("semana") || query.includes("week")) {
135
230
  const dayOfWeek = today.getDay();
136
231
  const diff = dayOfWeek === 0 ? -6 : 1 - dayOfWeek; // Monday is start
137
232
  const weekStart = new Date(today);
@@ -140,16 +235,18 @@ class Confirm8AgentTool {
140
235
  weekEnd.setDate(weekStart.getDate() + 6);
141
236
  return {
142
237
  start_date: { gte: formatDate(weekStart) },
143
- end_date: { lte: formatDate(weekEnd) }
238
+ end_date: { lte: formatDate(weekEnd) },
144
239
  };
145
240
  }
146
241
  // This month / mês atual
147
- if (query.includes('mês') || query.includes('mes') || query.includes('month')) {
242
+ if (query.includes("mês") ||
243
+ query.includes("mes") ||
244
+ query.includes("month")) {
148
245
  const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
149
246
  const monthEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0);
150
247
  return {
151
248
  start_date: { gte: formatDate(monthStart) },
152
- end_date: { lte: formatDate(monthEnd) }
249
+ end_date: { lte: formatDate(monthEnd) },
153
250
  };
154
251
  }
155
252
  // Last N days
@@ -160,7 +257,7 @@ class Confirm8AgentTool {
160
257
  startDate.setDate(today.getDate() - days);
161
258
  return {
162
259
  start_date: { gte: formatDate(startDate) },
163
- end_date: { lte: formatDate(today) }
260
+ end_date: { lte: formatDate(today) },
164
261
  };
165
262
  }
166
263
  // Next N days
@@ -171,7 +268,7 @@ class Confirm8AgentTool {
171
268
  endDate.setDate(today.getDate() + days);
172
269
  return {
173
270
  start_date: { gte: formatDate(today) },
174
- end_date: { lte: formatDate(endDate) }
271
+ end_date: { lte: formatDate(endDate) },
175
272
  };
176
273
  }
177
274
  return null;
@@ -181,16 +278,16 @@ class Confirm8AgentTool {
181
278
  const returnData = [];
182
279
  for (let i = 0; i < items.length; i++) {
183
280
  try {
184
- const baseUrl = this.getNodeParameter('baseUrl', i);
185
- const bearerToken = this.getNodeParameter('bearerToken', i);
186
- const apiDomain = this.getNodeParameter('apiDomain', i);
187
- const apiKeyToken = this.getNodeParameter('apiKeyToken', i);
188
- let resource = this.getNodeParameter('resource', i, '');
189
- let operation = this.getNodeParameter('operation', i, '');
190
- const recordId = this.getNodeParameter('recordId', i, '');
281
+ const baseUrl = this.getNodeParameter("baseUrl", i);
282
+ const bearerToken = this.getNodeParameter("bearerToken", i);
283
+ const apiDomain = this.getNodeParameter("apiDomain", i);
284
+ const apiKeyToken = this.getNodeParameter("apiKeyToken", i);
285
+ let resource = this.getNodeParameter("resource", i, "");
286
+ let operation = this.getNodeParameter("operation", i, "");
287
+ const recordId = this.getNodeParameter("recordId", i, "");
191
288
  // Parse data
192
289
  let data = {};
193
- const dataParam = this.getNodeParameter('data', i, '');
290
+ const dataParam = this.getNodeParameter("data", i, "");
194
291
  if (dataParam) {
195
292
  try {
196
293
  data = JSON.parse(dataParam);
@@ -201,7 +298,7 @@ class Confirm8AgentTool {
201
298
  }
202
299
  // Parse filters
203
300
  let filters = {};
204
- const filtersParam = this.getNodeParameter('filters', i, '');
301
+ const filtersParam = this.getNodeParameter("filters", i, "");
205
302
  if (filtersParam) {
206
303
  try {
207
304
  // Try to parse as JSON first
@@ -218,197 +315,284 @@ class Confirm8AgentTool {
218
315
  // Aggressive normalization - EXPAND THIS
219
316
  const resourceMap = {
220
317
  // Standard
221
- 'users': 'user', 'usuarios': 'user', 'usuários': 'user', 'employees': 'user', 'funcionários': 'user', 'funcionarios': 'user',
222
- 'clients': 'client', 'clientes': 'client', 'customers': 'client',
223
- 'items': 'item', 'itens': 'item',
224
- 'itemtypes': 'itemType', 'tipos': 'itemType',
225
- 'tasks': 'task', 'tarefas': 'task',
226
- 'services': 'service', 'serviços': 'service', 'servicos': 'service',
227
- 'products': 'product', 'produtos': 'product',
228
- 'modalities': 'modality', 'modalidades': 'modality',
229
- 'tickets': 'ticket', 'chamados': 'ticket',
230
- 'properties': 'property', 'propriedades': 'property',
318
+ users: "user",
319
+ usuarios: "user",
320
+ usuários: "user",
321
+ employees: "user",
322
+ funcionários: "user",
323
+ funcionarios: "user",
324
+ clients: "client",
325
+ clientes: "client",
326
+ customers: "client",
327
+ items: "item",
328
+ itens: "item",
329
+ itemtypes: "itemType",
330
+ tipos: "itemType",
331
+ tasks: "task",
332
+ tarefas: "task",
333
+ services: "service",
334
+ serviços: "service",
335
+ servicos: "service",
336
+ products: "product",
337
+ produtos: "product",
338
+ modalities: "modality",
339
+ modalidades: "modality",
340
+ tickets: "ticket",
341
+ chamados: "ticket",
342
+ properties: "property",
343
+ propriedades: "property",
231
344
  // 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',
345
+ os: "order",
346
+ "o.s": "order",
347
+ "o.s.": "order",
348
+ orders: "order",
349
+ ordens: "order",
350
+ ordem: "order",
351
+ "ordem de serviço": "order",
352
+ "ordem de servico": "order",
353
+ "ordens de serviço": "order",
354
+ "ordens de servico": "order",
355
+ wos: "order",
356
+ "work order": "order",
357
+ "work orders": "order",
358
+ pedidos: "order",
359
+ pedido: "order",
247
360
  };
248
361
  const operationMap = {
249
362
  // 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',
363
+ list: "getAll",
364
+ listar: "getAll",
365
+ mostrar: "getAll",
366
+ buscar: "getAll",
367
+ busque: "getAll",
368
+ "buscar todos": "getAll",
369
+ "buscar todas": "getAll",
370
+ "buscar todo": "getAll",
371
+ "buscar toda": "getAll",
372
+ "get all": "getAll",
373
+ "show all": "getAll",
374
+ "list all": "getAll",
375
+ todos: "getAll",
376
+ todas: "getAll",
377
+ "obter todos": "getAll",
378
+ "obter todas": "getAll",
379
+ "pegar todos": "getAll",
380
+ "pegar todas": "getAll",
268
381
  // Get Single
269
- 'obter': 'get',
270
- 'pegar': 'get',
271
- 'ver': 'get',
272
- 'visualizar': 'get',
382
+ obter: "get",
383
+ pegar: "get",
384
+ ver: "get",
385
+ visualizar: "get",
273
386
  // Create
274
- 'criar': 'create',
275
- 'adicionar': 'create',
276
- 'add': 'create',
277
- 'novo': 'create',
278
- 'nova': 'create',
279
- 'new': 'create',
387
+ criar: "create",
388
+ adicionar: "create",
389
+ add: "create",
390
+ novo: "create",
391
+ nova: "create",
392
+ new: "create",
280
393
  // Update
281
- 'atualizar': 'update',
282
- 'modificar': 'update',
283
- 'modify': 'update',
284
- 'editar': 'update',
285
- 'edit': 'update',
394
+ atualizar: "update",
395
+ modificar: "update",
396
+ modify: "update",
397
+ editar: "update",
398
+ edit: "update",
286
399
  // Activate/Deactivate
287
- 'ativar': 'activate',
288
- 'enable': 'activate',
289
- 'habilitar': 'activate',
290
- 'desativar': 'deactivate',
291
- 'disable': 'deactivate',
292
- 'desabilitar': 'deactivate',
400
+ ativar: "activate",
401
+ enable: "activate",
402
+ habilitar: "activate",
403
+ desativar: "deactivate",
404
+ disable: "deactivate",
405
+ desabilitar: "deactivate",
293
406
  };
294
407
  // Normalize - clean and map
295
- const cleanResource = resource.toLowerCase().trim().replace(/\s+/g, ' ');
296
- const cleanOperation = operation.toLowerCase().trim().replace(/\s+/g, ' ');
408
+ const normalizeKey = (value) => value
409
+ .toLowerCase()
410
+ .normalize("NFD")
411
+ .replace(/\p{Diacritic}/gu, "")
412
+ .replace(/[^a-z0-9\s.\-_/]/g, " ")
413
+ .trim()
414
+ .replace(/\s+/g, " ");
415
+ const cleanResource = normalizeKey(resource);
416
+ const cleanOperation = normalizeKey(operation);
297
417
  resource = resourceMap[cleanResource] || resource;
298
418
  operation = operationMap[cleanOperation] || operation;
299
419
  // 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'];
420
+ const validResources = VALID_RESOURCES;
421
+ const validOperations = VALID_OPERATIONS;
302
422
  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".`);
423
+ throw new Error(`Invalid resource: "${resource}". Must be one of: ${validResources.join(", ")}. ` + `For OS/Ordem de Serviço use "order".`);
305
424
  }
306
425
  if (!validOperations.includes(operation)) {
307
- throw new Error(`Invalid operation: "${operation}". Must be one of: ${validOperations.join(', ')}. ` +
308
- `To list/search use "getAll".`);
426
+ throw new Error(`Invalid operation: "${operation}". Must be one of: ${validOperations.join(", ")}. ` + `To list/search use "getAll".`);
309
427
  }
310
428
  // Resource config with relations
311
429
  const resourceConfig = {
312
430
  user: {
313
- endpoint: 'users',
314
- relations: ['clients', 'attachments', 'permissions', 'device', 'employee']
431
+ endpoint: "users",
432
+ relations: [
433
+ "clients",
434
+ "attachments",
435
+ "permissions",
436
+ "device",
437
+ "employee",
438
+ ],
315
439
  },
316
440
  client: {
317
- endpoint: 'clients',
318
- relations: ['wos', 'items', 'employees', 'headquarter', 'files', 'userGroup', 'properties']
441
+ endpoint: "clients",
442
+ relations: [
443
+ "wos",
444
+ "items",
445
+ "employees",
446
+ "headquarter",
447
+ "files",
448
+ "userGroup",
449
+ "properties",
450
+ ],
319
451
  },
320
452
  item: {
321
- endpoint: 'items',
322
- relations: ['client', 'item_type', 'properties', 'parent', 'children', 'collects', 'wos']
453
+ endpoint: "items",
454
+ relations: [
455
+ "client",
456
+ "item_type",
457
+ "properties",
458
+ "parent",
459
+ "children",
460
+ "collects",
461
+ "wos",
462
+ ],
323
463
  },
324
464
  itemType: {
325
- endpoint: 'itemTypes',
326
- relations: ['properties']
465
+ endpoint: "itemTypes",
466
+ relations: ["properties"],
327
467
  },
328
468
  task: {
329
- endpoint: 'tasks',
330
- relations: ['itemType', 'activities', 'wos', 'modalities']
469
+ endpoint: "tasks",
470
+ relations: ["itemType", "activities", "wos", "modalities"],
331
471
  },
332
472
  service: {
333
- endpoint: 'services',
334
- relations: ['task']
473
+ endpoint: "services",
474
+ relations: ["task"],
335
475
  },
336
476
  product: {
337
- endpoint: 'products',
338
- relations: []
477
+ endpoint: "products",
478
+ relations: [],
339
479
  },
340
480
  order: {
341
- endpoint: 'wos',
342
- relations: ['client', 'modalities', 'tasks', 'pivot_tasks', 'products', 'users', 'items', 'tickets', 'services', 'collects', 'attachments']
481
+ endpoint: "wos",
482
+ relations: [
483
+ "client",
484
+ "modalities",
485
+ "tasks",
486
+ "pivot_tasks",
487
+ "products",
488
+ "users",
489
+ "items",
490
+ "tickets",
491
+ "services",
492
+ "collects",
493
+ "attachments",
494
+ ],
343
495
  },
344
496
  modality: {
345
- endpoint: 'modalities',
346
- relations: ['tasks']
497
+ endpoint: "modalities",
498
+ relations: ["tasks"],
347
499
  },
348
500
  ticket: {
349
- endpoint: 'tickets',
350
- relations: ['client', 'subject_category', 'category', 'status', 'attachments', 'item', 'owner', 'priority', 'users', 'orders', 'properties']
501
+ endpoint: "tickets",
502
+ relations: [
503
+ "client",
504
+ "subject_category",
505
+ "category",
506
+ "status",
507
+ "attachments",
508
+ "item",
509
+ "owner",
510
+ "priority",
511
+ "users",
512
+ "orders",
513
+ "properties",
514
+ ],
351
515
  },
352
516
  property: {
353
- endpoint: 'properties',
354
- relations: []
517
+ endpoint: "properties",
518
+ relations: [],
355
519
  },
356
520
  };
357
521
  const config = resourceConfig[resource];
358
522
  const baseEndpoint = config.endpoint;
359
- let endpoint = '';
360
- let method = 'GET';
523
+ let endpoint = "";
524
+ let method = "GET";
361
525
  let body = {};
362
526
  // Build endpoint
363
527
  switch (operation) {
364
- case 'getAll':
528
+ case "getAll":
365
529
  endpoint = `/v3/${baseEndpoint}`;
366
530
  break;
367
- case 'get':
531
+ case "get":
368
532
  if (!recordId)
369
- throw new Error('recordId required');
533
+ throw new Error("recordId required");
370
534
  endpoint = `/v3/${baseEndpoint}/${recordId}`;
371
535
  break;
372
- case 'create':
536
+ case "create":
373
537
  endpoint = `/v3/${baseEndpoint}`;
374
- method = 'POST';
538
+ method = "POST";
375
539
  body = data;
376
540
  break;
377
- case 'update':
541
+ case "update":
378
542
  if (!recordId)
379
- throw new Error('recordId required');
543
+ throw new Error("recordId required");
380
544
  endpoint = `/v3/${baseEndpoint}/${recordId}`;
381
- method = 'PUT';
545
+ method = "PUT";
382
546
  body = data;
383
547
  break;
384
- case 'activate':
548
+ case "activate":
385
549
  if (!recordId)
386
- throw new Error('recordId required');
550
+ throw new Error("recordId required");
387
551
  endpoint = `/v3/${baseEndpoint}/${recordId}/active`;
388
- method = ['client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality'].includes(resource)
389
- ? 'PUT' : 'PATCH';
552
+ method = [
553
+ "client",
554
+ "item",
555
+ "itemType",
556
+ "task",
557
+ "service",
558
+ "product",
559
+ "order",
560
+ "modality",
561
+ ].includes(resource)
562
+ ? "PUT"
563
+ : "PATCH";
390
564
  break;
391
- case 'deactivate':
565
+ case "deactivate":
392
566
  if (!recordId)
393
- throw new Error('recordId required');
567
+ throw new Error("recordId required");
394
568
  endpoint = `/v3/${baseEndpoint}/${recordId}/inactive`;
395
- method = ['client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality'].includes(resource)
396
- ? 'PUT' : 'PATCH';
569
+ method = [
570
+ "client",
571
+ "item",
572
+ "itemType",
573
+ "task",
574
+ "service",
575
+ "product",
576
+ "order",
577
+ "modality",
578
+ ].includes(resource)
579
+ ? "PUT"
580
+ : "PATCH";
397
581
  break;
398
582
  }
399
583
  // Build query string
400
584
  const queryParams = [];
401
585
  // Add relations (only GET)
402
- if (method === 'GET' && config.relations.length > 0) {
403
- config.relations.forEach(relation => {
586
+ if (method === "GET" && config.relations.length > 0) {
587
+ config.relations.forEach((relation) => {
404
588
  queryParams.push(`relations=${relation}`);
405
589
  });
406
590
  }
407
591
  // Add filters
408
592
  if (Object.keys(filters).length > 0) {
409
- Object.keys(filters).forEach(field => {
593
+ Object.keys(filters).forEach((field) => {
410
594
  const operators = filters[field];
411
- Object.keys(operators).forEach(operator => {
595
+ Object.keys(operators).forEach((operator) => {
412
596
  const value = operators[operator];
413
597
  queryParams.push(`filters[${field}][${operator}]=${encodeURIComponent(String(value))}`);
414
598
  });
@@ -417,21 +601,23 @@ class Confirm8AgentTool {
417
601
  // Full URL
418
602
  let fullUrl = `${baseUrl}${endpoint}`;
419
603
  if (queryParams.length > 0) {
420
- fullUrl += '?' + queryParams.join('&');
604
+ fullUrl += "?" + queryParams.join("&");
421
605
  }
422
606
  // Make request
423
607
  const options = {
424
608
  method,
425
609
  uri: fullUrl,
426
610
  headers: {
427
- 'Authorization': `Bearer ${bearerToken}`,
428
- 'X-API-DOMAIN': apiDomain,
429
- 'X-APIKEY-TOKEN': apiKeyToken,
430
- 'Content-Type': 'application/json',
611
+ Authorization: `Bearer ${bearerToken}`,
612
+ "X-API-DOMAIN": apiDomain,
613
+ "X-APIKEY-TOKEN": apiKeyToken,
614
+ "Content-Type": "application/json",
431
615
  },
432
616
  json: true,
433
617
  };
434
- if (method !== 'GET' && method !== 'DELETE' && Object.keys(body).length > 0) {
618
+ if (method !== "GET" &&
619
+ method !== "DELETE" &&
620
+ Object.keys(body).length > 0) {
435
621
  options.body = body;
436
622
  }
437
623
  const responseData = await this.helpers.request(options);
@@ -439,8 +625,8 @@ class Confirm8AgentTool {
439
625
  json: {
440
626
  success: true,
441
627
  normalized: {
442
- originalResource: this.getNodeParameter('resource', i, ''),
443
- originalOperation: this.getNodeParameter('operation', i, ''),
628
+ originalResource: this.getNodeParameter("resource", i, ""),
629
+ originalOperation: this.getNodeParameter("operation", i, ""),
444
630
  normalizedResource: resource,
445
631
  normalizedOperation: operation,
446
632
  },
@@ -461,7 +647,7 @@ class Confirm8AgentTool {
461
647
  returnData.push({
462
648
  json: {
463
649
  success: false,
464
- error: error.message || 'Unknown error',
650
+ error: error.message || "Unknown error",
465
651
  },
466
652
  pairedItem: { item: i },
467
653
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-confirm8",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Simple n8n node for Confirm8 API - no credentials needed",
5
5
  "license": "MIT",
6
6
  "author": "Bill Hebert",