n8n-nodes-confirm8 0.23.0 → 0.24.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,17 +1,14 @@
|
|
|
1
1
|
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from "n8n-workflow";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* CONFIRM8 OS TOOL (CHUMBED)
|
|
4
|
+
* - resource is ALWAYS "order"
|
|
5
|
+
* - operation is ALWAYS "getAll" OR "get" (derived only from presence of recordId)
|
|
6
|
+
* - dates are ALWAYS ISO YYYY-MM-DD (validated / computed here)
|
|
7
|
+
*
|
|
8
|
+
* This is the recommended single-tool version to use inside an AI Agent.
|
|
9
|
+
* The agent never sees 'resource' or 'operation' parameters, so it cannot fill them wrong.
|
|
10
|
+
*/
|
|
11
|
+
export declare class Confirm8OSTool implements INodeType {
|
|
3
12
|
description: INodeTypeDescription;
|
|
4
|
-
/**
|
|
5
|
-
* Parse natural date queries into filter JSON
|
|
6
|
-
*/
|
|
7
|
-
private parseDateQuery;
|
|
8
|
-
/**
|
|
9
|
-
* Validate ISO date string yyyy-mm-dd
|
|
10
|
-
*/
|
|
11
|
-
private isIsoDate;
|
|
12
|
-
/**
|
|
13
|
-
* Enforce date filters format when present
|
|
14
|
-
*/
|
|
15
|
-
private validateDateFilters;
|
|
16
13
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
17
14
|
}
|
|
@@ -1,32 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
5
|
-
|
|
3
|
+
exports.Confirm8OSTool = void 0;
|
|
4
|
+
const confirm8_utils_1 = require("./confirm8.utils");
|
|
5
|
+
/**
|
|
6
|
+
* CONFIRM8 OS TOOL (CHUMBED)
|
|
7
|
+
* - resource is ALWAYS "order"
|
|
8
|
+
* - operation is ALWAYS "getAll" OR "get" (derived only from presence of recordId)
|
|
9
|
+
* - dates are ALWAYS ISO YYYY-MM-DD (validated / computed here)
|
|
10
|
+
*
|
|
11
|
+
* This is the recommended single-tool version to use inside an AI Agent.
|
|
12
|
+
* The agent never sees 'resource' or 'operation' parameters, so it cannot fill them wrong.
|
|
13
|
+
*/
|
|
14
|
+
class Confirm8OSTool {
|
|
6
15
|
constructor() {
|
|
7
16
|
this.description = {
|
|
8
|
-
displayName: "Confirm8 AI Tool",
|
|
9
|
-
name: "
|
|
17
|
+
displayName: "Confirm8 OS (Chumbed AI Tool)",
|
|
18
|
+
name: "confirm8OsTool",
|
|
10
19
|
icon: "file:tool.svg",
|
|
11
20
|
group: ["transform"],
|
|
12
21
|
version: 1,
|
|
13
|
-
description:
|
|
14
|
-
|
|
15
|
-
CRITICAL FOR AGENTS:
|
|
16
|
-
- "resource" MUST be exactly one of: user, client, item, itemType, task, service, product, order, modality, ticket, property
|
|
17
|
-
- "operation" MUST be exactly one of: getAll, get, create, update, activate, deactivate
|
|
18
|
-
- Use ONLY these tokens. Do NOT use labels like "OS", "Ordem de Serviço", "buscar".
|
|
19
|
-
- For OS/ordem de serviço => resource="order"
|
|
20
|
-
- To list/search => operation="getAll"
|
|
21
|
-
- Date filters MUST be ISO yyyy-mm-dd.`,
|
|
22
|
-
defaults: {
|
|
23
|
-
name: "Confirm8 AI Tool",
|
|
24
|
-
},
|
|
25
|
-
usableAsTool: true,
|
|
22
|
+
description: "Work Orders (OS) tool for Confirm8. CHUMBED: resource/order is fixed; operation is derived internally (getAll vs get). Dates are always ISO YYYY-MM-DD.",
|
|
23
|
+
defaults: { name: "Confirm8 OS" },
|
|
26
24
|
inputs: ["main"],
|
|
27
25
|
outputs: ["main"],
|
|
28
26
|
properties: [
|
|
29
|
-
// API Configuration
|
|
30
27
|
{
|
|
31
28
|
displayName: "Base URL",
|
|
32
29
|
name: "baseUrl",
|
|
@@ -44,243 +41,97 @@ CRITICAL FOR AGENTS:
|
|
|
44
41
|
required: true,
|
|
45
42
|
},
|
|
46
43
|
{
|
|
47
|
-
displayName: "
|
|
44
|
+
displayName: "API Domain",
|
|
48
45
|
name: "apiDomain",
|
|
49
46
|
type: "string",
|
|
50
47
|
default: "",
|
|
51
48
|
required: true,
|
|
52
49
|
},
|
|
53
50
|
{
|
|
54
|
-
displayName: "
|
|
51
|
+
displayName: "API Key Token",
|
|
55
52
|
name: "apiKeyToken",
|
|
56
53
|
type: "string",
|
|
57
54
|
typeOptions: { password: true },
|
|
58
55
|
default: "",
|
|
59
56
|
required: true,
|
|
60
57
|
},
|
|
61
|
-
// Tool parameters
|
|
62
58
|
{
|
|
63
|
-
displayName: "
|
|
64
|
-
name: "
|
|
65
|
-
type: "
|
|
66
|
-
|
|
67
|
-
{
|
|
68
|
-
name: "user",
|
|
69
|
-
value: "user",
|
|
70
|
-
description: "Users/Employees/Funcionários",
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
name: "client",
|
|
74
|
-
value: "client",
|
|
75
|
-
description: "Clients/Customers/Clientes",
|
|
76
|
-
},
|
|
77
|
-
{ name: "item", value: "item", description: "Items/Itens" },
|
|
78
|
-
{
|
|
79
|
-
name: "itemType",
|
|
80
|
-
value: "itemType",
|
|
81
|
-
description: "Item Types/Tipos",
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: "task",
|
|
85
|
-
value: "task",
|
|
86
|
-
description: "Tasks/Tarefas/Checklists",
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
name: "service",
|
|
90
|
-
value: "service",
|
|
91
|
-
description: "Services/Serviços",
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
name: "product",
|
|
95
|
-
value: "product",
|
|
96
|
-
description: "Products/Produtos",
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: "order",
|
|
100
|
-
value: "order",
|
|
101
|
-
description: "Work Orders/OS/Ordens de Serviço/WOS",
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
name: "modality",
|
|
105
|
-
value: "modality",
|
|
106
|
-
description: "Modalities/Modalidades",
|
|
107
|
-
},
|
|
108
|
-
{ name: "ticket", value: "ticket", description: "Tickets/Chamados" },
|
|
109
|
-
{
|
|
110
|
-
name: "property",
|
|
111
|
-
value: "property",
|
|
112
|
-
description: "Properties/Propriedades",
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
default: "user",
|
|
116
|
-
description: `CRITICAL (Agents): Resource MUST be EXACTLY one of: user, client, item, itemType, task, service, product, order, modality, ticket, property.
|
|
117
|
-
Use ONLY the value token (example: order), never labels like OS.`,
|
|
59
|
+
displayName: "Session ID",
|
|
60
|
+
name: "sessionId",
|
|
61
|
+
type: "string",
|
|
62
|
+
default: "",
|
|
118
63
|
},
|
|
119
64
|
{
|
|
120
|
-
displayName: "
|
|
121
|
-
name: "
|
|
122
|
-
type: "
|
|
123
|
-
|
|
124
|
-
{
|
|
125
|
-
name: "getAll",
|
|
126
|
-
value: "getAll",
|
|
127
|
-
description: "List/Listar/Buscar todos/Mostrar todos",
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: "get",
|
|
131
|
-
value: "get",
|
|
132
|
-
description: "Get one/Buscar um/Obter",
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
name: "create",
|
|
136
|
-
value: "create",
|
|
137
|
-
description: "Create/Criar/Adicionar",
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
name: "update",
|
|
141
|
-
value: "update",
|
|
142
|
-
description: "Update/Atualizar/Modificar",
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
name: "activate",
|
|
146
|
-
value: "activate",
|
|
147
|
-
description: "Activate/Ativar",
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
name: "deactivate",
|
|
151
|
-
value: "deactivate",
|
|
152
|
-
description: "Deactivate/Desativar",
|
|
153
|
-
},
|
|
154
|
-
],
|
|
155
|
-
default: "getAll",
|
|
156
|
-
description: `CRITICAL (Agents): Operation MUST be EXACTLY one of: getAll, get, create, update, activate, deactivate.
|
|
157
|
-
Use ONLY the value token (example: getAll), never labels like buscar.`,
|
|
65
|
+
displayName: "User Query (Optional)",
|
|
66
|
+
name: "chatinput",
|
|
67
|
+
type: "string",
|
|
68
|
+
default: "",
|
|
158
69
|
},
|
|
70
|
+
// If filled, tool performs GET by ID; otherwise, GET ALL (list)
|
|
159
71
|
{
|
|
160
|
-
displayName: "
|
|
72
|
+
displayName: "OS ID (recordId)",
|
|
161
73
|
name: "recordId",
|
|
162
74
|
type: "string",
|
|
163
75
|
default: "",
|
|
164
|
-
description: "
|
|
76
|
+
description: "If provided, fetches a single OS (get). If empty, lists OS (getAll).",
|
|
77
|
+
},
|
|
78
|
+
// Listing options (only relevant when recordId is empty)
|
|
79
|
+
{
|
|
80
|
+
displayName: "Date Range",
|
|
81
|
+
name: "dateRange",
|
|
82
|
+
type: "options",
|
|
83
|
+
default: "thisWeek",
|
|
84
|
+
displayOptions: { show: { recordId: [""] } },
|
|
85
|
+
options: [
|
|
86
|
+
{ name: "This week (Mon..Sun)", value: "thisWeek" },
|
|
87
|
+
{ name: "Custom", value: "custom" },
|
|
88
|
+
],
|
|
165
89
|
},
|
|
166
90
|
{
|
|
167
|
-
displayName: "
|
|
168
|
-
name: "
|
|
91
|
+
displayName: "Start Date (YYYY-MM-DD)",
|
|
92
|
+
name: "startDate",
|
|
169
93
|
type: "string",
|
|
170
94
|
default: "",
|
|
171
|
-
|
|
95
|
+
displayOptions: { show: { dateRange: ["custom"], recordId: [""] } },
|
|
172
96
|
},
|
|
173
97
|
{
|
|
174
|
-
displayName: "
|
|
175
|
-
name: "
|
|
98
|
+
displayName: "End Date (YYYY-MM-DD)",
|
|
99
|
+
name: "endDate",
|
|
176
100
|
type: "string",
|
|
177
101
|
default: "",
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
102
|
+
displayOptions: { show: { dateRange: ["custom"], recordId: [""] } },
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
displayName: "Date Field",
|
|
106
|
+
name: "dateField",
|
|
107
|
+
type: "options",
|
|
108
|
+
default: "created_at",
|
|
109
|
+
displayOptions: { show: { recordId: [""] } },
|
|
110
|
+
options: [
|
|
111
|
+
{ name: "created_at (recommended)", value: "created_at" },
|
|
112
|
+
{ name: "date", value: "date" },
|
|
113
|
+
{ name: "data", value: "data" },
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
displayName: "Per Page",
|
|
118
|
+
name: "perPage",
|
|
119
|
+
type: "number",
|
|
120
|
+
default: 50,
|
|
121
|
+
displayOptions: { show: { recordId: [""] } },
|
|
122
|
+
typeOptions: { minValue: 1, maxValue: 200 },
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
displayName: "Page",
|
|
126
|
+
name: "page",
|
|
127
|
+
type: "number",
|
|
128
|
+
default: 1,
|
|
129
|
+
displayOptions: { show: { recordId: [""] } },
|
|
130
|
+
typeOptions: { minValue: 1 },
|
|
182
131
|
},
|
|
183
132
|
],
|
|
184
133
|
};
|
|
185
134
|
}
|
|
186
|
-
/**
|
|
187
|
-
* Parse natural date queries into filter JSON
|
|
188
|
-
*/
|
|
189
|
-
parseDateQuery(query) {
|
|
190
|
-
const now = new Date();
|
|
191
|
-
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
192
|
-
query = query.toLowerCase().trim();
|
|
193
|
-
// Helper to format date as YYYY-MM-DD
|
|
194
|
-
const formatDate = (date) => {
|
|
195
|
-
return date.toISOString().split("T")[0];
|
|
196
|
-
};
|
|
197
|
-
// Today
|
|
198
|
-
if (query.includes("hoje") || query.includes("today")) {
|
|
199
|
-
const endOfDay = new Date(today);
|
|
200
|
-
endOfDay.setHours(23, 59, 59, 999);
|
|
201
|
-
return {
|
|
202
|
-
start_date: { gte: formatDate(today) },
|
|
203
|
-
end_date: { lte: formatDate(endOfDay) },
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
// This week / semana atual
|
|
207
|
-
if (query.includes("semana") || query.includes("week")) {
|
|
208
|
-
const dayOfWeek = today.getDay();
|
|
209
|
-
const diff = dayOfWeek === 0 ? -6 : 1 - dayOfWeek; // Monday is start
|
|
210
|
-
const weekStart = new Date(today);
|
|
211
|
-
weekStart.setDate(today.getDate() + diff);
|
|
212
|
-
const weekEnd = new Date(weekStart);
|
|
213
|
-
weekEnd.setDate(weekStart.getDate() + 6);
|
|
214
|
-
return {
|
|
215
|
-
start_date: { gte: formatDate(weekStart) },
|
|
216
|
-
end_date: { lte: formatDate(weekEnd) },
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
// This month / mês atual
|
|
220
|
-
if (query.includes("mês") ||
|
|
221
|
-
query.includes("mes") ||
|
|
222
|
-
query.includes("month")) {
|
|
223
|
-
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
224
|
-
const monthEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0);
|
|
225
|
-
return {
|
|
226
|
-
start_date: { gte: formatDate(monthStart) },
|
|
227
|
-
end_date: { lte: formatDate(monthEnd) },
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
// Last N days
|
|
231
|
-
const lastDaysMatch = query.match(/últimos?\s+(\d+)\s+dias?|last\s+(\d+)\s+days?/);
|
|
232
|
-
if (lastDaysMatch) {
|
|
233
|
-
const days = parseInt(lastDaysMatch[1] || lastDaysMatch[2]);
|
|
234
|
-
const startDate = new Date(today);
|
|
235
|
-
startDate.setDate(today.getDate() - days);
|
|
236
|
-
return {
|
|
237
|
-
start_date: { gte: formatDate(startDate) },
|
|
238
|
-
end_date: { lte: formatDate(today) },
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
// Next N days
|
|
242
|
-
const nextDaysMatch = query.match(/próximos?\s+(\d+)\s+dias?|next\s+(\d+)\s+days?/);
|
|
243
|
-
if (nextDaysMatch) {
|
|
244
|
-
const days = parseInt(nextDaysMatch[1] || nextDaysMatch[2]);
|
|
245
|
-
const endDate = new Date(today);
|
|
246
|
-
endDate.setDate(today.getDate() + days);
|
|
247
|
-
return {
|
|
248
|
-
start_date: { gte: formatDate(today) },
|
|
249
|
-
end_date: { lte: formatDate(endDate) },
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
return null;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Validate ISO date string yyyy-mm-dd
|
|
256
|
-
*/
|
|
257
|
-
isIsoDate(value) {
|
|
258
|
-
if (typeof value !== "string")
|
|
259
|
-
return false;
|
|
260
|
-
return /^\d{4}-\d{2}-\d{2}$/.test(value);
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Enforce date filters format when present
|
|
264
|
-
*/
|
|
265
|
-
validateDateFilters(filters) {
|
|
266
|
-
const dateFields = ["start_date", "end_date", "date", "data"];
|
|
267
|
-
for (const field of dateFields) {
|
|
268
|
-
if (!filters[field])
|
|
269
|
-
continue;
|
|
270
|
-
const ops = filters[field];
|
|
271
|
-
if (!ops || typeof ops !== "object")
|
|
272
|
-
continue;
|
|
273
|
-
for (const op of Object.keys(ops)) {
|
|
274
|
-
const v = ops[op];
|
|
275
|
-
if (v == null)
|
|
276
|
-
continue;
|
|
277
|
-
if (!this.isIsoDate(v)) {
|
|
278
|
-
throw new Error(`Invalid date format in filters["${field}"]["${op}"]="${String(v)}". ` +
|
|
279
|
-
`Dates MUST be yyyy-mm-dd (ISO), e.g. "2025-06-16".`);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
135
|
async execute() {
|
|
285
136
|
const items = this.getInputData();
|
|
286
137
|
const returnData = [];
|
|
@@ -290,402 +141,98 @@ Do NOT send expressions like "data >= start_of_week".`,
|
|
|
290
141
|
const bearerToken = this.getNodeParameter("bearerToken", i);
|
|
291
142
|
const apiDomain = this.getNodeParameter("apiDomain", i);
|
|
292
143
|
const apiKeyToken = this.getNodeParameter("apiKeyToken", i);
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
const recordId = this.getNodeParameter("recordId", i, "");
|
|
296
|
-
//
|
|
297
|
-
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
}
|
|
315
|
-
catch (e) {
|
|
316
|
-
// If not JSON, try to parse as natural language date query
|
|
317
|
-
const parsedDate = this.parseDateQuery(filtersParam);
|
|
318
|
-
if (parsedDate) {
|
|
319
|
-
filters = parsedDate;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
// Enforce ISO date filters when present
|
|
323
|
-
this.validateDateFilters(filters);
|
|
324
|
-
}
|
|
325
|
-
// Aggressive normalization - EXPAND THIS
|
|
326
|
-
const resourceMap = {
|
|
327
|
-
// Standard
|
|
328
|
-
users: "user",
|
|
329
|
-
usuarios: "user",
|
|
330
|
-
usuários: "user",
|
|
331
|
-
employees: "user",
|
|
332
|
-
funcionários: "user",
|
|
333
|
-
funcionarios: "user",
|
|
334
|
-
clients: "client",
|
|
335
|
-
clientes: "client",
|
|
336
|
-
customers: "client",
|
|
337
|
-
items: "item",
|
|
338
|
-
itens: "item",
|
|
339
|
-
itemtypes: "itemType",
|
|
340
|
-
tipos: "itemType",
|
|
341
|
-
tasks: "task",
|
|
342
|
-
tarefas: "task",
|
|
343
|
-
services: "service",
|
|
344
|
-
serviços: "service",
|
|
345
|
-
servicos: "service",
|
|
346
|
-
products: "product",
|
|
347
|
-
produtos: "product",
|
|
348
|
-
modalities: "modality",
|
|
349
|
-
modalidades: "modality",
|
|
350
|
-
tickets: "ticket",
|
|
351
|
-
chamados: "ticket",
|
|
352
|
-
properties: "property",
|
|
353
|
-
propriedades: "property",
|
|
354
|
-
// CRITICAL: OS mappings
|
|
355
|
-
os: "order",
|
|
356
|
-
"o.s": "order",
|
|
357
|
-
"o.s.": "order",
|
|
358
|
-
orders: "order",
|
|
359
|
-
ordens: "order",
|
|
360
|
-
ordem: "order",
|
|
361
|
-
"ordem de serviço": "order",
|
|
362
|
-
"ordem de servico": "order",
|
|
363
|
-
"ordens de serviço": "order",
|
|
364
|
-
"ordens de servico": "order",
|
|
365
|
-
wos: "order",
|
|
366
|
-
"work order": "order",
|
|
367
|
-
"work orders": "order",
|
|
368
|
-
pedidos: "order",
|
|
369
|
-
pedido: "order",
|
|
370
|
-
};
|
|
371
|
-
const operationMap = {
|
|
372
|
-
// List/Get All
|
|
373
|
-
list: "getAll",
|
|
374
|
-
listar: "getAll",
|
|
375
|
-
mostrar: "getAll",
|
|
376
|
-
buscar: "getAll",
|
|
377
|
-
busque: "getAll",
|
|
378
|
-
"buscar todos": "getAll",
|
|
379
|
-
"buscar todas": "getAll",
|
|
380
|
-
"buscar todo": "getAll",
|
|
381
|
-
"buscar toda": "getAll",
|
|
382
|
-
"get all": "getAll",
|
|
383
|
-
"show all": "getAll",
|
|
384
|
-
"list all": "getAll",
|
|
385
|
-
todos: "getAll",
|
|
386
|
-
todas: "getAll",
|
|
387
|
-
"obter todos": "getAll",
|
|
388
|
-
"obter todas": "getAll",
|
|
389
|
-
"pegar todos": "getAll",
|
|
390
|
-
"pegar todas": "getAll",
|
|
391
|
-
// Get Single
|
|
392
|
-
obter: "get",
|
|
393
|
-
pegar: "get",
|
|
394
|
-
ver: "get",
|
|
395
|
-
visualizar: "get",
|
|
396
|
-
// Create
|
|
397
|
-
criar: "create",
|
|
398
|
-
adicionar: "create",
|
|
399
|
-
add: "create",
|
|
400
|
-
novo: "create",
|
|
401
|
-
nova: "create",
|
|
402
|
-
new: "create",
|
|
403
|
-
// Update
|
|
404
|
-
atualizar: "update",
|
|
405
|
-
modificar: "update",
|
|
406
|
-
modify: "update",
|
|
407
|
-
editar: "update",
|
|
408
|
-
edit: "update",
|
|
409
|
-
// Activate/Deactivate
|
|
410
|
-
ativar: "activate",
|
|
411
|
-
enable: "activate",
|
|
412
|
-
habilitar: "activate",
|
|
413
|
-
desativar: "deactivate",
|
|
414
|
-
disable: "deactivate",
|
|
415
|
-
desabilitar: "deactivate",
|
|
416
|
-
};
|
|
417
|
-
// Normalize - clean and map (remove accents/punctuation)
|
|
418
|
-
const normalizeKey = (value) => value
|
|
419
|
-
.toLowerCase()
|
|
420
|
-
.normalize("NFD")
|
|
421
|
-
.replace(/\p{Diacritic}/gu, "")
|
|
422
|
-
.replace(/[^a-z0-9\s.\-_/]/g, " ")
|
|
423
|
-
.trim()
|
|
424
|
-
.replace(/\s+/g, " ");
|
|
425
|
-
const cleanResource = normalizeKey(resource);
|
|
426
|
-
const cleanOperation = normalizeKey(operation);
|
|
427
|
-
resource = resourceMap[cleanResource] || resource;
|
|
428
|
-
operation = operationMap[cleanOperation] || operation;
|
|
429
|
-
// If still not valid, throw clear error
|
|
430
|
-
const validResources = [
|
|
431
|
-
"user",
|
|
432
|
-
"client",
|
|
433
|
-
"item",
|
|
434
|
-
"itemType",
|
|
435
|
-
"task",
|
|
436
|
-
"service",
|
|
437
|
-
"product",
|
|
438
|
-
"order",
|
|
439
|
-
"modality",
|
|
440
|
-
"ticket",
|
|
441
|
-
"property",
|
|
442
|
-
];
|
|
443
|
-
const validOperations = [
|
|
444
|
-
"getAll",
|
|
445
|
-
"get",
|
|
446
|
-
"create",
|
|
447
|
-
"update",
|
|
448
|
-
"activate",
|
|
449
|
-
"deactivate",
|
|
450
|
-
];
|
|
451
|
-
if (!validResources.includes(resource)) {
|
|
452
|
-
throw new Error(`Invalid resource: "${resource}". Must be one of: ${validResources.join(", ")}. ` + `For OS/Ordem de Serviço use "order".`);
|
|
453
|
-
}
|
|
454
|
-
if (!validOperations.includes(operation)) {
|
|
455
|
-
throw new Error(`Invalid operation: "${operation}". Must be one of: ${validOperations.join(", ")}. ` + `To list/search use "getAll".`);
|
|
456
|
-
}
|
|
457
|
-
// Resource config with relations
|
|
458
|
-
const resourceConfig = {
|
|
459
|
-
user: {
|
|
460
|
-
endpoint: "users",
|
|
461
|
-
relations: [
|
|
462
|
-
"clients",
|
|
463
|
-
"attachments",
|
|
464
|
-
"permissions",
|
|
465
|
-
"device",
|
|
466
|
-
"employee",
|
|
467
|
-
],
|
|
468
|
-
},
|
|
469
|
-
client: {
|
|
470
|
-
endpoint: "clients",
|
|
471
|
-
relations: [
|
|
472
|
-
"wos",
|
|
473
|
-
"items",
|
|
474
|
-
"employees",
|
|
475
|
-
"headquarter",
|
|
476
|
-
"files",
|
|
477
|
-
"userGroup",
|
|
478
|
-
"properties",
|
|
479
|
-
],
|
|
480
|
-
},
|
|
481
|
-
item: {
|
|
482
|
-
endpoint: "items",
|
|
483
|
-
relations: [
|
|
484
|
-
"client",
|
|
485
|
-
"item_type",
|
|
486
|
-
"properties",
|
|
487
|
-
"parent",
|
|
488
|
-
"children",
|
|
489
|
-
"collects",
|
|
490
|
-
"wos",
|
|
491
|
-
],
|
|
492
|
-
},
|
|
493
|
-
itemType: {
|
|
494
|
-
endpoint: "itemTypes",
|
|
495
|
-
relations: ["properties"],
|
|
496
|
-
},
|
|
497
|
-
task: {
|
|
498
|
-
endpoint: "tasks",
|
|
499
|
-
relations: ["itemType", "activities", "wos", "modalities"],
|
|
500
|
-
},
|
|
501
|
-
service: {
|
|
502
|
-
endpoint: "services",
|
|
503
|
-
relations: ["task"],
|
|
504
|
-
},
|
|
505
|
-
product: {
|
|
506
|
-
endpoint: "products",
|
|
507
|
-
relations: [],
|
|
508
|
-
},
|
|
509
|
-
order: {
|
|
510
|
-
endpoint: "wos",
|
|
511
|
-
relations: [
|
|
512
|
-
"client",
|
|
513
|
-
"modalities",
|
|
514
|
-
"tasks",
|
|
515
|
-
"pivot_tasks",
|
|
516
|
-
"products",
|
|
517
|
-
"users",
|
|
518
|
-
"items",
|
|
519
|
-
"tickets",
|
|
520
|
-
"services",
|
|
521
|
-
"collects",
|
|
522
|
-
"attachments",
|
|
523
|
-
],
|
|
524
|
-
},
|
|
525
|
-
modality: {
|
|
526
|
-
endpoint: "modalities",
|
|
527
|
-
relations: ["tasks"],
|
|
528
|
-
},
|
|
529
|
-
ticket: {
|
|
530
|
-
endpoint: "tickets",
|
|
531
|
-
relations: [
|
|
532
|
-
"client",
|
|
533
|
-
"subject_category",
|
|
534
|
-
"category",
|
|
535
|
-
"status",
|
|
536
|
-
"attachments",
|
|
537
|
-
"item",
|
|
538
|
-
"owner",
|
|
539
|
-
"priority",
|
|
540
|
-
"users",
|
|
541
|
-
"orders",
|
|
542
|
-
"properties",
|
|
543
|
-
],
|
|
544
|
-
},
|
|
545
|
-
property: {
|
|
546
|
-
endpoint: "properties",
|
|
547
|
-
relations: [],
|
|
548
|
-
},
|
|
549
|
-
};
|
|
550
|
-
const config = resourceConfig[resource];
|
|
551
|
-
const baseEndpoint = config.endpoint;
|
|
552
|
-
let endpoint = "";
|
|
553
|
-
let method = "GET";
|
|
554
|
-
let body = {};
|
|
555
|
-
// Build endpoint
|
|
556
|
-
switch (operation) {
|
|
557
|
-
case "getAll":
|
|
558
|
-
endpoint = `/v3/${baseEndpoint}`;
|
|
559
|
-
break;
|
|
560
|
-
case "get":
|
|
561
|
-
if (!recordId)
|
|
562
|
-
throw new Error("recordId required");
|
|
563
|
-
endpoint = `/v3/${baseEndpoint}/${recordId}`;
|
|
564
|
-
break;
|
|
565
|
-
case "create":
|
|
566
|
-
endpoint = `/v3/${baseEndpoint}`;
|
|
567
|
-
method = "POST";
|
|
568
|
-
body = data;
|
|
569
|
-
break;
|
|
570
|
-
case "update":
|
|
571
|
-
if (!recordId)
|
|
572
|
-
throw new Error("recordId required");
|
|
573
|
-
endpoint = `/v3/${baseEndpoint}/${recordId}`;
|
|
574
|
-
method = "PUT";
|
|
575
|
-
body = data;
|
|
576
|
-
break;
|
|
577
|
-
case "activate":
|
|
578
|
-
if (!recordId)
|
|
579
|
-
throw new Error("recordId required");
|
|
580
|
-
endpoint = `/v3/${baseEndpoint}/${recordId}/active`;
|
|
581
|
-
method = [
|
|
582
|
-
"client",
|
|
583
|
-
"item",
|
|
584
|
-
"itemType",
|
|
585
|
-
"task",
|
|
586
|
-
"service",
|
|
587
|
-
"product",
|
|
588
|
-
"order",
|
|
589
|
-
"modality",
|
|
590
|
-
].includes(resource)
|
|
591
|
-
? "PUT"
|
|
592
|
-
: "PATCH";
|
|
593
|
-
break;
|
|
594
|
-
case "deactivate":
|
|
595
|
-
if (!recordId)
|
|
596
|
-
throw new Error("recordId required");
|
|
597
|
-
endpoint = `/v3/${baseEndpoint}/${recordId}/inactive`;
|
|
598
|
-
method = [
|
|
599
|
-
"client",
|
|
600
|
-
"item",
|
|
601
|
-
"itemType",
|
|
602
|
-
"task",
|
|
603
|
-
"service",
|
|
604
|
-
"product",
|
|
605
|
-
"order",
|
|
606
|
-
"modality",
|
|
607
|
-
].includes(resource)
|
|
608
|
-
? "PUT"
|
|
609
|
-
: "PATCH";
|
|
610
|
-
break;
|
|
611
|
-
}
|
|
612
|
-
// Build query string
|
|
613
|
-
const queryParams = [];
|
|
614
|
-
// Add relations (only GET)
|
|
615
|
-
if (method === "GET" && config.relations.length > 0) {
|
|
616
|
-
config.relations.forEach((relation) => {
|
|
617
|
-
queryParams.push(`relations=${relation}`);
|
|
144
|
+
const sessionId = this.getNodeParameter("sessionId", i, "");
|
|
145
|
+
const chatinput = this.getNodeParameter("chatinput", i, "");
|
|
146
|
+
const recordId = this.getNodeParameter("recordId", i, "").trim();
|
|
147
|
+
// CHUMBED RESOURCE
|
|
148
|
+
const resource = "order";
|
|
149
|
+
const config = confirm8_utils_1.RESOURCE_ENDPOINTS[resource];
|
|
150
|
+
// Decide operation internally
|
|
151
|
+
const operation = recordId ? "get" : "getAll";
|
|
152
|
+
if (operation === "get") {
|
|
153
|
+
const endpoint = `/v3/${config.endpoint}/${encodeURIComponent(recordId)}`;
|
|
154
|
+
const query = config.relations?.length
|
|
155
|
+
? `?${config.relations.map((r) => `relations=${encodeURIComponent(r)}`).join("&")}`
|
|
156
|
+
: "";
|
|
157
|
+
const data = await confirm8_utils_1.confirm8Request.call(this, i, {
|
|
158
|
+
baseUrl,
|
|
159
|
+
bearerToken,
|
|
160
|
+
apiDomain,
|
|
161
|
+
apiKeyToken,
|
|
162
|
+
method: "GET",
|
|
163
|
+
endpoint,
|
|
164
|
+
query,
|
|
618
165
|
});
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
});
|
|
166
|
+
returnData.push({
|
|
167
|
+
json: {
|
|
168
|
+
success: true,
|
|
169
|
+
fixed: { resource, operation },
|
|
170
|
+
request: { sessionId, chatinput, recordId, endpoint },
|
|
171
|
+
data,
|
|
172
|
+
},
|
|
173
|
+
pairedItem: { item: i },
|
|
628
174
|
});
|
|
175
|
+
continue;
|
|
629
176
|
}
|
|
630
|
-
//
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
177
|
+
// operation === getAll
|
|
178
|
+
const dateRange = this.getNodeParameter("dateRange", i);
|
|
179
|
+
const dateField = this.getNodeParameter("dateField", i);
|
|
180
|
+
let start;
|
|
181
|
+
let end;
|
|
182
|
+
if (dateRange === "custom") {
|
|
183
|
+
start = this.getNodeParameter("startDate", i) || "";
|
|
184
|
+
end = this.getNodeParameter("endDate", i) || "";
|
|
185
|
+
if (!start || !end) {
|
|
186
|
+
throw new Error("When Date Range is Custom, startDate and endDate are required.");
|
|
187
|
+
}
|
|
188
|
+
(0, confirm8_utils_1.assertIsoDate)(start, "startDate");
|
|
189
|
+
(0, confirm8_utils_1.assertIsoDate)(end, "endDate");
|
|
634
190
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
headers: {
|
|
640
|
-
Authorization: `Bearer ${bearerToken}`,
|
|
641
|
-
"X-API-DOMAIN": apiDomain,
|
|
642
|
-
"X-APIKEY-TOKEN": apiKeyToken,
|
|
643
|
-
"Content-Type": "application/json",
|
|
644
|
-
},
|
|
645
|
-
json: true,
|
|
646
|
-
};
|
|
647
|
-
if (method !== "GET" &&
|
|
648
|
-
method !== "DELETE" &&
|
|
649
|
-
Object.keys(body).length > 0) {
|
|
650
|
-
options.body = body;
|
|
191
|
+
else {
|
|
192
|
+
const r = (0, confirm8_utils_1.getThisWeekRange)(new Date());
|
|
193
|
+
start = r.start;
|
|
194
|
+
end = r.end;
|
|
651
195
|
}
|
|
652
|
-
const
|
|
196
|
+
const endpoint = `/v3/${config.endpoint}`;
|
|
197
|
+
const filters = { [dateField]: { gte: start, lte: end } };
|
|
198
|
+
const page = this.getNodeParameter("page", i);
|
|
199
|
+
const perPage = this.getNodeParameter("perPage", i);
|
|
200
|
+
const query = (0, confirm8_utils_1.buildQueryParams)(config.relations, filters);
|
|
201
|
+
const pagination = `&page=${encodeURIComponent(String(page))}&per_page=${encodeURIComponent(String(perPage))}`;
|
|
202
|
+
const finalQuery = query ? `${query}${pagination}` : `?page=${page}&per_page=${perPage}`;
|
|
203
|
+
const data = await confirm8_utils_1.confirm8Request.call(this, i, {
|
|
204
|
+
baseUrl,
|
|
205
|
+
bearerToken,
|
|
206
|
+
apiDomain,
|
|
207
|
+
apiKeyToken,
|
|
208
|
+
method: "GET",
|
|
209
|
+
endpoint,
|
|
210
|
+
query: finalQuery,
|
|
211
|
+
});
|
|
653
212
|
returnData.push({
|
|
654
213
|
json: {
|
|
655
214
|
success: true,
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
method,
|
|
669
|
-
data: responseData,
|
|
215
|
+
fixed: { resource, operation },
|
|
216
|
+
request: {
|
|
217
|
+
sessionId,
|
|
218
|
+
chatinput,
|
|
219
|
+
endpoint,
|
|
220
|
+
dateField,
|
|
221
|
+
startDate: start,
|
|
222
|
+
endDate: end,
|
|
223
|
+
page,
|
|
224
|
+
perPage,
|
|
225
|
+
},
|
|
226
|
+
data,
|
|
670
227
|
},
|
|
671
228
|
pairedItem: { item: i },
|
|
672
229
|
});
|
|
673
230
|
}
|
|
674
|
-
catch (
|
|
675
|
-
|
|
676
|
-
returnData.push({
|
|
677
|
-
json: {
|
|
678
|
-
success: false,
|
|
679
|
-
error: error.message || "Unknown error",
|
|
680
|
-
},
|
|
681
|
-
pairedItem: { item: i },
|
|
682
|
-
});
|
|
683
|
-
continue;
|
|
684
|
-
}
|
|
685
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, { itemIndex: i });
|
|
231
|
+
catch (err) {
|
|
232
|
+
throw (0, confirm8_utils_1.toNodeError)(this.getNode(), err, i);
|
|
686
233
|
}
|
|
687
234
|
}
|
|
688
235
|
return [returnData];
|
|
689
236
|
}
|
|
690
237
|
}
|
|
691
|
-
exports.
|
|
238
|
+
exports.Confirm8OSTool = Confirm8OSTool;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IDataObject, NodeOperationError, IExecuteFunctions } from "n8n-workflow";
|
|
2
|
+
export declare const VALID_RESOURCES: readonly ["user", "client", "item", "itemType", "task", "service", "product", "order", "modality", "ticket", "property"];
|
|
3
|
+
export declare const VALID_OPERATIONS: readonly ["getAll", "get", "create", "update", "activate", "deactivate"];
|
|
4
|
+
export type Confirm8Resource = (typeof VALID_RESOURCES)[number];
|
|
5
|
+
export type Confirm8Operation = (typeof VALID_OPERATIONS)[number];
|
|
6
|
+
export declare const RESOURCE_ENDPOINTS: Record<Confirm8Resource, {
|
|
7
|
+
endpoint: string;
|
|
8
|
+
relations: string[];
|
|
9
|
+
}>;
|
|
10
|
+
export declare function assertIsoDate(dateStr: string, label: string): void;
|
|
11
|
+
export declare function formatIsoDate(d: Date): string;
|
|
12
|
+
/**
|
|
13
|
+
* Week starts on Monday (pt-BR business default).
|
|
14
|
+
* Returns inclusive start/end in YYYY-MM-DD.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getThisWeekRange(now?: Date): {
|
|
17
|
+
start: string;
|
|
18
|
+
end: string;
|
|
19
|
+
};
|
|
20
|
+
/** Build query params for relations + filters in Confirm8 format. */
|
|
21
|
+
export declare function buildQueryParams(relations: string[], filters?: IDataObject): string;
|
|
22
|
+
export declare function confirm8Request(this: IExecuteFunctions, i: number, args: {
|
|
23
|
+
baseUrl: string;
|
|
24
|
+
bearerToken: string;
|
|
25
|
+
apiDomain: string;
|
|
26
|
+
apiKeyToken: string;
|
|
27
|
+
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
28
|
+
endpoint: string;
|
|
29
|
+
query?: string;
|
|
30
|
+
body?: IDataObject;
|
|
31
|
+
}): Promise<any>;
|
|
32
|
+
export declare function toNodeError(node: any, err: unknown, i: number): NodeOperationError;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RESOURCE_ENDPOINTS = exports.VALID_OPERATIONS = exports.VALID_RESOURCES = void 0;
|
|
4
|
+
exports.assertIsoDate = assertIsoDate;
|
|
5
|
+
exports.formatIsoDate = formatIsoDate;
|
|
6
|
+
exports.getThisWeekRange = getThisWeekRange;
|
|
7
|
+
exports.buildQueryParams = buildQueryParams;
|
|
8
|
+
exports.confirm8Request = confirm8Request;
|
|
9
|
+
exports.toNodeError = toNodeError;
|
|
10
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
11
|
+
exports.VALID_RESOURCES = [
|
|
12
|
+
"user",
|
|
13
|
+
"client",
|
|
14
|
+
"item",
|
|
15
|
+
"itemType",
|
|
16
|
+
"task",
|
|
17
|
+
"service",
|
|
18
|
+
"product",
|
|
19
|
+
"order",
|
|
20
|
+
"modality",
|
|
21
|
+
"ticket",
|
|
22
|
+
"property",
|
|
23
|
+
];
|
|
24
|
+
exports.VALID_OPERATIONS = [
|
|
25
|
+
"getAll",
|
|
26
|
+
"get",
|
|
27
|
+
"create",
|
|
28
|
+
"update",
|
|
29
|
+
"activate",
|
|
30
|
+
"deactivate",
|
|
31
|
+
];
|
|
32
|
+
exports.RESOURCE_ENDPOINTS = {
|
|
33
|
+
user: {
|
|
34
|
+
endpoint: "users",
|
|
35
|
+
relations: ["clients", "attachments", "permissions", "device", "employee"],
|
|
36
|
+
},
|
|
37
|
+
client: {
|
|
38
|
+
endpoint: "clients",
|
|
39
|
+
relations: [
|
|
40
|
+
"address",
|
|
41
|
+
"contacts",
|
|
42
|
+
"items",
|
|
43
|
+
"tickets",
|
|
44
|
+
"orders",
|
|
45
|
+
"properties",
|
|
46
|
+
"attachments",
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
item: {
|
|
50
|
+
endpoint: "items",
|
|
51
|
+
relations: ["client", "itemType", "properties", "attachments"],
|
|
52
|
+
},
|
|
53
|
+
itemType: { endpoint: "item-types", relations: ["properties"] },
|
|
54
|
+
task: {
|
|
55
|
+
endpoint: "tasks",
|
|
56
|
+
relations: ["itemType", "modality", "services", "products"],
|
|
57
|
+
},
|
|
58
|
+
service: { endpoint: "services", relations: ["task"] },
|
|
59
|
+
product: { endpoint: "products", relations: [] },
|
|
60
|
+
// IMPORTANT: Confirm8 Work Orders endpoint is 'wos'
|
|
61
|
+
order: {
|
|
62
|
+
endpoint: "wos",
|
|
63
|
+
relations: [
|
|
64
|
+
"client",
|
|
65
|
+
"modalities",
|
|
66
|
+
"tasks",
|
|
67
|
+
"pivot_tasks",
|
|
68
|
+
"products",
|
|
69
|
+
"users",
|
|
70
|
+
"items",
|
|
71
|
+
"tickets",
|
|
72
|
+
"services",
|
|
73
|
+
"collects",
|
|
74
|
+
"attachments",
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
modality: { endpoint: "modalities", relations: ["tasks"] },
|
|
78
|
+
ticket: {
|
|
79
|
+
endpoint: "tickets",
|
|
80
|
+
relations: ["client", "subject_category", "category", "user", "attachments"],
|
|
81
|
+
},
|
|
82
|
+
property: { endpoint: "properties", relations: ["client", "item", "itemType"] },
|
|
83
|
+
};
|
|
84
|
+
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
85
|
+
function assertIsoDate(dateStr, label) {
|
|
86
|
+
if (!ISO_DATE.test(dateStr)) {
|
|
87
|
+
throw new Error(`${label} must be in YYYY-MM-DD format. Received: "${dateStr}"`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function formatIsoDate(d) {
|
|
91
|
+
const y = d.getFullYear();
|
|
92
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
93
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
94
|
+
return `${y}-${m}-${day}`;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Week starts on Monday (pt-BR business default).
|
|
98
|
+
* Returns inclusive start/end in YYYY-MM-DD.
|
|
99
|
+
*/
|
|
100
|
+
function getThisWeekRange(now = new Date()) {
|
|
101
|
+
const d = new Date(now);
|
|
102
|
+
d.setHours(0, 0, 0, 0);
|
|
103
|
+
// JS: Sunday=0 ... Saturday=6
|
|
104
|
+
const day = d.getDay();
|
|
105
|
+
const diffToMonday = day === 0 ? -6 : 1 - day; // if Sunday -> go back 6 days
|
|
106
|
+
const startDate = new Date(d);
|
|
107
|
+
startDate.setDate(d.getDate() + diffToMonday);
|
|
108
|
+
const endDate = new Date(startDate);
|
|
109
|
+
endDate.setDate(startDate.getDate() + 6);
|
|
110
|
+
return { start: formatIsoDate(startDate), end: formatIsoDate(endDate) };
|
|
111
|
+
}
|
|
112
|
+
/** Build query params for relations + filters in Confirm8 format. */
|
|
113
|
+
function buildQueryParams(relations, filters) {
|
|
114
|
+
const queryParams = [];
|
|
115
|
+
if (relations?.length) {
|
|
116
|
+
for (const rel of relations)
|
|
117
|
+
queryParams.push(`relations=${encodeURIComponent(rel)}`);
|
|
118
|
+
}
|
|
119
|
+
if (filters && Object.keys(filters).length) {
|
|
120
|
+
for (const field of Object.keys(filters)) {
|
|
121
|
+
const operators = filters[field];
|
|
122
|
+
for (const op of Object.keys(operators)) {
|
|
123
|
+
const value = operators[op];
|
|
124
|
+
queryParams.push(`filters[${encodeURIComponent(field)}][${encodeURIComponent(op)}]=${encodeURIComponent(String(value))}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return queryParams.length ? `?${queryParams.join("&")}` : "";
|
|
129
|
+
}
|
|
130
|
+
function confirm8Request(i, args) {
|
|
131
|
+
const { baseUrl, bearerToken, apiDomain, apiKeyToken, method, endpoint, query, body } = args;
|
|
132
|
+
const uri = `${baseUrl}${endpoint}${query ?? ""}`;
|
|
133
|
+
const options = {
|
|
134
|
+
method,
|
|
135
|
+
uri,
|
|
136
|
+
headers: {
|
|
137
|
+
Authorization: `Bearer ${bearerToken}`,
|
|
138
|
+
"X-API-DOMAIN": apiDomain,
|
|
139
|
+
"X-APIKEY-TOKEN": apiKeyToken,
|
|
140
|
+
"Content-Type": "application/json",
|
|
141
|
+
},
|
|
142
|
+
json: true,
|
|
143
|
+
};
|
|
144
|
+
if (body && method !== "GET" && method !== "DELETE") {
|
|
145
|
+
options.body = body;
|
|
146
|
+
}
|
|
147
|
+
return this.helpers.request(options);
|
|
148
|
+
}
|
|
149
|
+
function toNodeError(node, err, i) {
|
|
150
|
+
if (err instanceof n8n_workflow_1.NodeOperationError)
|
|
151
|
+
return err;
|
|
152
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
153
|
+
return new n8n_workflow_1.NodeOperationError(node, message, { itemIndex: i });
|
|
154
|
+
}
|