n8n-nodes-innotes 2.0.17 → 2.0.19

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,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * @author Marco
4
- * @date 2025-06-28
4
+ * @date 2026-09-14
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.InNotes = void 0;
@@ -14,6 +14,80 @@ const StatusDescription_1 = require("../../descriptions/StatusDescription");
14
14
  const TagDescription_1 = require("../../descriptions/TagDescription");
15
15
  const UserDescription_1 = require("../../descriptions/UserDescription");
16
16
  const AutomationDescription_1 = require("../../descriptions/AutomationDescription");
17
+ /**
18
+ * One authenticated call to the InNotes API.
19
+ *
20
+ * `Content-Type` is derived from the presence of a body and `qs` is spread only
21
+ * when given: that is what every call site sent before this helper existed, and
22
+ * a header or an empty `qs` added here would change all of them at once.
23
+ *
24
+ * HTTP only: response normalisation and every catch block stay at the call site.
25
+ *
26
+ * @author Marco
27
+ * @date 2026-09-09
28
+ */
29
+ async function apiRequest(ctx, method, path, options = {}) {
30
+ const credentials = await ctx.getCredentials('inNotesApi');
31
+ return ctx.helpers.httpRequestWithAuthentication.call(ctx, 'inNotesApi', {
32
+ method,
33
+ url: `${credentials.baseUrl}${path}`,
34
+ ...(options.qs ? { qs: options.qs } : {}),
35
+ ...(options.body ? { body: options.body } : {}),
36
+ headers: {
37
+ Accept: 'application/json',
38
+ ...(options.body ? { 'Content-Type': 'application/json' } : {}),
39
+ },
40
+ });
41
+ }
42
+ /**
43
+ * Fail on an unusable credential BEFORE entering a catch that would absorb it.
44
+ *
45
+ * `apiRequest` resolves the credential per request, i.e. inside whatever try the
46
+ * caller wrote. Two of those catches answer a failure with a successful "does not
47
+ * exist" item — one always, the other under continueOnFail — so a credential
48
+ * fault resolved in there would report that the job does not exist. Call this
49
+ * first at those sites; do not delete it because the result is unused.
50
+ *
51
+ * @author Marco
52
+ * @date 2026-09-09
53
+ */
54
+ async function assertCredentials(ctx) {
55
+ await ctx.getCredentials('inNotesApi');
56
+ }
57
+ /**
58
+ * Resolve a job status NAME to its numeric id, case-insensitively.
59
+ *
60
+ * The caller keeps the decision about what to do with the result: job create
61
+ * drops a falsy id from the body, job update assigns it unconditionally. That
62
+ * divergence predates this helper and is preserved unchanged; whether it was
63
+ * ever intended is not established — see the two call sites.
64
+ *
65
+ * @author Marco
66
+ * @date 2026-09-09
67
+ */
68
+ async function resolveJobStatusId(executeFunctions, statusName) {
69
+ try {
70
+ const statusResponse = await apiRequest(executeFunctions, 'GET', '/api/statuses', {
71
+ qs: { type: 'job' },
72
+ });
73
+ const statuses = Array.isArray(statusResponse) ? statusResponse : [statusResponse];
74
+ const matchingStatus = statuses.find((s) => { var _a; return ((_a = s.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === statusName.toLowerCase(); });
75
+ if (!matchingStatus) {
76
+ throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
77
+ message: `Status "${statusName}" not found. Available statuses: ${statuses.map((s) => s.name).join(', ')}`,
78
+ });
79
+ }
80
+ return parseInt(matchingStatus.id, 10);
81
+ }
82
+ catch (error) {
83
+ if (error instanceof n8n_workflow_1.NodeApiError) {
84
+ throw error;
85
+ }
86
+ throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
87
+ message: `Failed to lookup status "${statusName}": ${error.message}`,
88
+ });
89
+ }
90
+ }
17
91
  /**
18
92
  * Turn the "Phone & Email" fixedCollection into the array the API takes.
19
93
  *
@@ -181,15 +255,8 @@ class InNotes {
181
255
  loadOptions: {
182
256
  async jobStatuses() {
183
257
  try {
184
- const credentials = await this.getCredentials('inNotesApi');
185
- const baseUrl = credentials.baseUrl;
186
- const response = await this.helpers.httpRequestWithAuthentication.call(this, 'inNotesApi', {
187
- method: 'GET',
188
- url: `${baseUrl}/api/statuses`,
258
+ const response = await apiRequest(this, 'GET', '/api/statuses', {
189
259
  qs: { type: 'job' },
190
- headers: {
191
- Accept: 'application/json',
192
- },
193
260
  });
194
261
  const statuses = Array.isArray(response) ? response : [response];
195
262
  return statuses.map((status) => ({
@@ -216,13 +283,12 @@ class InNotes {
216
283
  const options = this.getNodeParameter('options', 0, {});
217
284
  const batchSize = options.batchSize || 10;
218
285
  const timeoutBetweenBatches = options.timeoutBetweenBatches || 1000;
219
- // Create a node instance to access the methods
220
- const nodeInstance = new InNotes();
221
286
  // Helper function to add delay between batches
222
287
  const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
223
288
  if (resource === 'job' && operation === 'batchExists') {
224
- const credentials = await this.getCredentials('inNotesApi');
225
- const baseUrl = credentials.baseUrl;
289
+ // Under continueOnFail the catch in the loop answers a failure with
290
+ // exists:false for every id.
291
+ await assertCredentials(this);
226
292
  const batchLimit = 200;
227
293
  const idsRaw = this.getNodeParameter('ids', 0, '');
228
294
  const allExtIds = idsRaw.split(',').map(id => id.trim()).filter(id => id.length > 0);
@@ -233,13 +299,7 @@ class InNotes {
233
299
  for (let offset = 0; offset < allExtIds.length; offset += batchLimit) {
234
300
  const chunk = allExtIds.slice(offset, offset + batchLimit);
235
301
  try {
236
- const response = await this.helpers.httpRequestWithAuthentication.call(this, 'inNotesApi', {
237
- method: 'POST',
238
- url: `${baseUrl}/api/job/batch-exists`,
239
- headers: {
240
- Accept: 'application/json',
241
- 'Content-Type': 'application/json',
242
- },
302
+ const response = await apiRequest(this, 'POST', '/api/job/batch-exists', {
243
303
  body: { ext_ids: chunk },
244
304
  });
245
305
  const results = (_a = response.results) !== null && _a !== void 0 ? _a : {};
@@ -274,25 +334,25 @@ class InNotes {
274
334
  try {
275
335
  let responseData = {};
276
336
  if (resource === 'automation') {
277
- responseData = await nodeInstance.executeAutomationOperation(this, actualIndex, operation);
337
+ responseData = await InNotes.executeAutomationOperation(this, actualIndex, operation);
278
338
  }
279
339
  else if (resource === 'contact') {
280
- responseData = await nodeInstance.executeContactOperation(this, actualIndex, operation);
340
+ responseData = await InNotes.executeContactOperation(this, actualIndex, operation);
281
341
  }
282
342
  else if (resource === 'note') {
283
- responseData = await nodeInstance.executeNoteOperation(this, actualIndex, operation);
343
+ responseData = await InNotes.executeNoteOperation(this, actualIndex, operation);
284
344
  }
285
345
  else if (resource === 'job') {
286
- responseData = await nodeInstance.executeJobOperation(this, actualIndex, operation);
346
+ responseData = await InNotes.executeJobOperation(this, actualIndex, operation);
287
347
  }
288
348
  else if (resource === 'status') {
289
- responseData = await nodeInstance.executeStatusOperation(this, actualIndex, operation);
349
+ responseData = await InNotes.executeStatusOperation(this, actualIndex, operation);
290
350
  }
291
351
  else if (resource === 'tag') {
292
- responseData = await nodeInstance.executeTagOperation(this, actualIndex, operation);
352
+ responseData = await InNotes.executeTagOperation(this, actualIndex, operation);
293
353
  }
294
354
  else if (resource === 'user') {
295
- responseData = await nodeInstance.executeUserOperation(this, actualIndex, operation);
355
+ responseData = await InNotes.executeUserOperation(this, actualIndex, operation);
296
356
  }
297
357
  if (Array.isArray(responseData)) {
298
358
  returnData.push(...responseData);
@@ -316,19 +376,10 @@ class InNotes {
316
376
  }
317
377
  return [this.helpers.returnJsonArray(returnData)];
318
378
  }
319
- async executeAutomationOperation(executeFunctions, itemIndex, operation) {
320
- const credentials = await executeFunctions.getCredentials('inNotesApi');
321
- const baseUrl = credentials.baseUrl;
379
+ static async executeAutomationOperation(executeFunctions, itemIndex, operation) {
322
380
  if (operation === 'getConfig') {
323
381
  try {
324
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
325
- method: 'GET',
326
- url: `${baseUrl}/api/automation/config`,
327
- headers: {
328
- Accept: 'application/json',
329
- },
330
- });
331
- return response;
382
+ return await apiRequest(executeFunctions, 'GET', '/api/automation/config');
332
383
  }
333
384
  catch (error) {
334
385
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
@@ -341,6 +392,7 @@ class InNotes {
341
392
  const status = executeFunctions.getNodeParameter('status', itemIndex, 'success');
342
393
  const errorMessage = executeFunctions.getNodeParameter('errorMessage', itemIndex, '');
343
394
  // Get the callback secret from credentials
395
+ const credentials = await executeFunctions.getCredentials('inNotesApi');
344
396
  const callbackSecret = credentials.callbackSecret;
345
397
  if (!callbackSecret) {
346
398
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
@@ -350,13 +402,7 @@ class InNotes {
350
402
  // Get user ID from the API
351
403
  let userId;
352
404
  try {
353
- const userResponse = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
354
- method: 'GET',
355
- url: `${baseUrl}/api/user`,
356
- headers: {
357
- Accept: 'application/json',
358
- },
359
- });
405
+ const userResponse = await apiRequest(executeFunctions, 'GET', '/api/user');
360
406
  userId = userResponse.id;
361
407
  }
362
408
  catch (error) {
@@ -372,15 +418,7 @@ class InNotes {
372
418
  ...(status === 'error' && errorMessage && { error: errorMessage }),
373
419
  };
374
420
  try {
375
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
376
- method: 'POST',
377
- url: `${baseUrl}/api/automation/callback`,
378
- body,
379
- headers: {
380
- Accept: 'application/json',
381
- 'Content-Type': 'application/json',
382
- },
383
- });
421
+ const response = await apiRequest(executeFunctions, 'POST', '/api/automation/callback', { body });
384
422
  return {
385
423
  success: true,
386
424
  ...response,
@@ -398,9 +436,7 @@ class InNotes {
398
436
  message: `The operation "${operation}" is not supported for resource "automation"!`,
399
437
  });
400
438
  }
401
- async executeContactOperation(executeFunctions, itemIndex, operation) {
402
- const credentials = await executeFunctions.getCredentials('inNotesApi');
403
- const baseUrl = credentials.baseUrl;
439
+ static async executeContactOperation(executeFunctions, itemIndex, operation) {
404
440
  if (operation === 'create') {
405
441
  const name = executeFunctions.getNodeParameter('name', itemIndex);
406
442
  const linkedin_key = executeFunctions.getNodeParameter('linkedin_key', itemIndex);
@@ -423,33 +459,16 @@ class InNotes {
423
459
  ...(contact_details && { contact_details }),
424
460
  };
425
461
  try {
426
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
427
- method: 'POST',
428
- url: `${baseUrl}/api/contacts`,
429
- body,
430
- headers: {
431
- Accept: 'application/json',
432
- 'Content-Type': 'application/json',
433
- },
434
- });
435
- return response;
462
+ return await apiRequest(executeFunctions, 'POST', '/api/contacts', { body });
436
463
  }
437
464
  catch (error) {
438
- const requestParams = {
439
- name,
440
- linkedin_key,
441
- ...(linkedin_user && { linkedin_user }),
442
- ...(location && { location }),
443
- ...(current_company && { current_company }),
444
- ...(picture_url && { picture_url }),
445
- ...(tags && { tags: tags.split(',').map((tag) => tag.trim()) }),
446
- ...(status_id && { status_id }),
447
- // The COUNT, never the values: this object is interpolated into a
448
- // NodeApiError message and n8n persists execution data, so the
449
- // numbers and addresses would sit in a third party's workflow
450
- // history. Author: Marco, 2026-08-10
451
- ...(contact_details && { contact_details: `${contact_details.length} entr(y|ies)` }),
452
- };
465
+ // The COUNT, never the values: this object is interpolated into a
466
+ // NodeApiError message and n8n persists execution data, so the
467
+ // numbers and addresses would sit in a third party's workflow
468
+ // history. Author: Marco, 2026-08-10
469
+ const requestParams = contact_details
470
+ ? { ...body, contact_details: `${contact_details.length} entr(y|ies)` }
471
+ : body;
453
472
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
454
473
  message: `Failed to create contact: ${error.message}. Request parameters: ${JSON.stringify(requestParams, null, 2)}`,
455
474
  });
@@ -457,14 +476,7 @@ class InNotes {
457
476
  }
458
477
  if (operation === 'get') {
459
478
  const contactId = executeFunctions.getNodeParameter('contactId', itemIndex);
460
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
461
- method: 'GET',
462
- url: `${baseUrl}/api/contacts/${contactId}`,
463
- headers: {
464
- Accept: 'application/json',
465
- },
466
- });
467
- return response;
479
+ return await apiRequest(executeFunctions, 'GET', `/api/contacts/${contactId}`);
468
480
  }
469
481
  if (operation === 'getAll') {
470
482
  const returnAll = executeFunctions.getNodeParameter('returnAll', itemIndex, false);
@@ -480,14 +492,7 @@ class InNotes {
480
492
  qs.pageSize = limit;
481
493
  qs.page = 1;
482
494
  }
483
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
484
- method: 'GET',
485
- url: `${baseUrl}/api/contacts`,
486
- qs,
487
- headers: {
488
- Accept: 'application/json',
489
- },
490
- });
495
+ const response = await apiRequest(executeFunctions, 'GET', '/api/contacts', { qs });
491
496
  return Array.isArray(response) ? response : [response];
492
497
  }
493
498
  if (operation === 'update') {
@@ -505,35 +510,18 @@ class InNotes {
505
510
  };
506
511
  if (contact_details === undefined)
507
512
  delete body.contact_details;
508
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
509
- method: 'PUT',
510
- url: `${baseUrl}/api/contacts/${contactId}`,
511
- body,
512
- headers: {
513
- Accept: 'application/json',
514
- 'Content-Type': 'application/json',
515
- },
516
- });
517
- return response;
513
+ return await apiRequest(executeFunctions, 'PUT', `/api/contacts/${contactId}`, { body });
518
514
  }
519
515
  if (operation === 'delete') {
520
516
  const contactId = executeFunctions.getNodeParameter('contactId', itemIndex);
521
- await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
522
- method: 'DELETE',
523
- url: `${baseUrl}/api/contacts/${contactId}`,
524
- headers: {
525
- Accept: 'application/json',
526
- },
527
- });
517
+ await apiRequest(executeFunctions, 'DELETE', `/api/contacts/${contactId}`);
528
518
  return { success: true };
529
519
  }
530
520
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
531
521
  message: `The operation "${operation}" is not supported for resource "contact"!`,
532
522
  });
533
523
  }
534
- async executeNoteOperation(executeFunctions, itemIndex, operation) {
535
- const credentials = await executeFunctions.getCredentials('inNotesApi');
536
- const baseUrl = credentials.baseUrl;
524
+ static async executeNoteOperation(executeFunctions, itemIndex, operation) {
537
525
  if (operation === 'create') {
538
526
  const content = executeFunctions.getNodeParameter('content', itemIndex);
539
527
  const contactId = executeFunctions.getNodeParameter('contactId', itemIndex);
@@ -545,81 +533,17 @@ class InNotes {
545
533
  ...(visibility && { visibility }),
546
534
  ...(ext_table_name && { ext_table_name }),
547
535
  };
548
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
549
- method: 'POST',
550
- url: `${baseUrl}/api/note`,
551
- body,
552
- headers: {
553
- Accept: 'application/json',
554
- 'Content-Type': 'application/json',
555
- },
556
- });
557
- return response;
536
+ return await apiRequest(executeFunctions, 'POST', '/api/note', { body });
558
537
  }
559
538
  if (operation === 'get') {
560
539
  const noteId = executeFunctions.getNodeParameter('noteId', itemIndex);
561
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
562
- method: 'GET',
563
- url: `${baseUrl}/api/note/${noteId}`,
564
- headers: {
565
- Accept: 'application/json',
566
- },
567
- });
568
- return response;
569
- }
570
- if (operation === 'getAll') {
571
- const contactId = executeFunctions.getNodeParameter('contactId', itemIndex);
572
- const returnAll = executeFunctions.getNodeParameter('returnAll', itemIndex, false);
573
- const qs = {
574
- contact_id: contactId,
575
- };
576
- if (!returnAll) {
577
- const limit = executeFunctions.getNodeParameter('limit', itemIndex, 24);
578
- qs.pageSize = limit;
579
- qs.page = 1;
580
- }
581
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
582
- method: 'GET',
583
- url: `${baseUrl}/api/note`,
584
- qs,
585
- headers: {
586
- Accept: 'application/json',
587
- },
588
- });
589
- return Array.isArray(response) ? response : [response];
590
- }
591
- if (operation === 'update') {
592
- const noteId = executeFunctions.getNodeParameter('noteId', itemIndex);
593
- const updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);
594
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
595
- method: 'PUT',
596
- url: `${baseUrl}/api/note/${noteId}`,
597
- body: updateFields,
598
- headers: {
599
- Accept: 'application/json',
600
- 'Content-Type': 'application/json',
601
- },
602
- });
603
- return response;
604
- }
605
- if (operation === 'delete') {
606
- const noteId = executeFunctions.getNodeParameter('noteId', itemIndex);
607
- await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
608
- method: 'DELETE',
609
- url: `${baseUrl}/api/note/${noteId}`,
610
- headers: {
611
- Accept: 'application/json',
612
- },
613
- });
614
- return { success: true };
540
+ return await apiRequest(executeFunctions, 'GET', `/api/note/${noteId}`);
615
541
  }
616
542
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
617
543
  message: `The operation "${operation}" is not supported for resource "note"!`,
618
544
  });
619
545
  }
620
- async executeJobOperation(executeFunctions, itemIndex, operation) {
621
- const credentials = await executeFunctions.getCredentials('inNotesApi');
622
- const baseUrl = credentials.baseUrl;
546
+ static async executeJobOperation(executeFunctions, itemIndex, operation) {
623
547
  if (operation === 'create') {
624
548
  const name = executeFunctions.getNodeParameter('name', itemIndex);
625
549
  const company_name = executeFunctions.getNodeParameter('company_name', itemIndex);
@@ -636,36 +560,7 @@ class InNotes {
636
560
  let status_id;
637
561
  // If status is provided, lookup the status ID
638
562
  if (status) {
639
- try {
640
- // Get all job statuses
641
- const statusResponse = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
642
- method: 'GET',
643
- url: `${baseUrl}/api/statuses`,
644
- qs: { type: 'job' },
645
- headers: {
646
- Accept: 'application/json',
647
- },
648
- });
649
- // Find matching status by name (case-insensitive)
650
- const statuses = Array.isArray(statusResponse) ? statusResponse : [statusResponse];
651
- const matchingStatus = statuses.find((s) => { var _a; return ((_a = s.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === status.toLowerCase(); });
652
- if (matchingStatus) {
653
- status_id = parseInt(matchingStatus.id, 10);
654
- }
655
- else {
656
- throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
657
- message: `Status "${status}" not found. Available statuses: ${statuses.map((s) => s.name).join(', ')}`,
658
- });
659
- }
660
- }
661
- catch (error) {
662
- if (error instanceof n8n_workflow_1.NodeApiError) {
663
- throw error;
664
- }
665
- throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
666
- message: `Failed to lookup status "${status}": ${error.message}`,
667
- });
668
- }
563
+ status_id = await resolveJobStatusId(executeFunctions, status);
669
564
  }
670
565
  const body = {
671
566
  name,
@@ -682,48 +577,18 @@ class InNotes {
682
577
  ...(tags && { tags: tags.split(',').map((tag) => tag.trim()) }),
683
578
  };
684
579
  try {
685
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
686
- method: 'POST',
687
- url: `${baseUrl}/api/job`,
688
- body,
689
- headers: {
690
- Accept: 'application/json',
691
- 'Content-Type': 'application/json',
692
- },
693
- });
694
- return response;
580
+ return await apiRequest(executeFunctions, 'POST', '/api/job', { body });
695
581
  }
696
582
  catch (error) {
697
- const requestParams = {
698
- name,
699
- company_name,
700
- ...(description && { description }),
701
- ...(location && { location }),
702
- ...(remote_setting && { remote_setting }),
703
- ...(company_url && { company_url }),
704
- ...(provider && { provider }),
705
- ...(url && { url }),
706
- ...(status_id && { status_id }),
707
- ...(ext_id && { ext_id }),
708
- ...(picture_url && picture_url !== 'Not Available' && { picture_url }),
709
- ...(tags && { tags: tags.split(',').map((tag) => tag.trim()) }),
710
- };
711
583
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
712
- message: `Failed to create job: ${error.message}. Request parameters: ${JSON.stringify(requestParams, null, 2)}`,
584
+ message: `Failed to create job: ${error.message}. Request parameters: ${JSON.stringify(body, null, 2)}`,
713
585
  });
714
586
  }
715
587
  }
716
588
  if (operation === 'get') {
717
589
  const jobId = executeFunctions.getNodeParameter('jobId', itemIndex);
718
590
  try {
719
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
720
- method: 'GET',
721
- url: `${baseUrl}/api/job/${jobId}`,
722
- headers: {
723
- Accept: 'application/json',
724
- },
725
- });
726
- return response;
591
+ return await apiRequest(executeFunctions, 'GET', `/api/job/${jobId}`);
727
592
  }
728
593
  catch (error) {
729
594
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
@@ -746,14 +611,7 @@ class InNotes {
746
611
  qs.page = 1;
747
612
  }
748
613
  try {
749
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
750
- method: 'GET',
751
- url: `${baseUrl}/api/job`,
752
- qs,
753
- headers: {
754
- Accept: 'application/json',
755
- },
756
- });
614
+ const response = await apiRequest(executeFunctions, 'GET', '/api/job', { qs });
757
615
  return Array.isArray(response) ? response : [response];
758
616
  }
759
617
  catch (error) {
@@ -767,54 +625,15 @@ class InNotes {
767
625
  const updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);
768
626
  // Handle status string lookup if provided
769
627
  if (updateFields.status && typeof updateFields.status === 'string') {
770
- try {
771
- // Get all job statuses
772
- const statusResponse = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
773
- method: 'GET',
774
- url: `${baseUrl}/api/statuses`,
775
- qs: { type: 'job' },
776
- headers: {
777
- Accept: 'application/json',
778
- },
779
- });
780
- // Find matching status by name (case-insensitive)
781
- const statuses = Array.isArray(statusResponse) ? statusResponse : [statusResponse];
782
- const matchingStatus = statuses.find((s) => { var _a; return ((_a = s.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === updateFields.status.toLowerCase(); });
783
- if (matchingStatus) {
784
- // Replace status with status_id and remove status field
785
- updateFields.status_id = parseInt(matchingStatus.id, 10);
786
- delete updateFields.status;
787
- }
788
- else {
789
- throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
790
- message: `Status "${updateFields.status}" not found. Available statuses: ${statuses.map((s) => s.name).join(', ')}`,
791
- });
792
- }
793
- }
794
- catch (error) {
795
- if (error instanceof n8n_workflow_1.NodeApiError) {
796
- throw error;
797
- }
798
- throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
799
- message: `Failed to lookup status "${updateFields.status}": ${error.message}`,
800
- });
801
- }
628
+ updateFields.status_id = await resolveJobStatusId(executeFunctions, updateFields.status);
629
+ delete updateFields.status;
802
630
  }
803
631
  // Process tags if provided as comma-separated string
804
632
  if (updateFields.tags && typeof updateFields.tags === 'string') {
805
633
  updateFields.tags = (updateFields.tags).split(',').map((tag) => tag.trim());
806
634
  }
807
635
  try {
808
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
809
- method: 'PUT',
810
- url: `${baseUrl}/api/job/${jobId}`,
811
- body: updateFields,
812
- headers: {
813
- Accept: 'application/json',
814
- 'Content-Type': 'application/json',
815
- },
816
- });
817
- return response;
636
+ return await apiRequest(executeFunctions, 'PUT', `/api/job/${jobId}`, { body: updateFields });
818
637
  }
819
638
  catch (error) {
820
639
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
@@ -825,13 +644,7 @@ class InNotes {
825
644
  if (operation === 'delete') {
826
645
  const jobId = executeFunctions.getNodeParameter('jobId', itemIndex);
827
646
  try {
828
- await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
829
- method: 'DELETE',
830
- url: `${baseUrl}/api/job/${jobId}`,
831
- headers: {
832
- Accept: 'application/json',
833
- },
834
- });
647
+ await apiRequest(executeFunctions, 'DELETE', `/api/job/${jobId}`);
835
648
  return { success: true };
836
649
  }
837
650
  catch (error) {
@@ -883,40 +696,24 @@ class InNotes {
883
696
  const limit = searchOptions.limit || 24;
884
697
  qs.pageSize = limit;
885
698
  qs.page = 1;
886
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
887
- method: 'GET',
888
- url: `${baseUrl}/api/job`,
889
- qs,
890
- headers: {
891
- Accept: 'application/json',
892
- },
893
- });
699
+ const response = await apiRequest(executeFunctions, 'GET', '/api/job', { qs });
894
700
  return Array.isArray(response) ? response : [response];
895
701
  }
896
702
  if (operation === 'exists') {
897
703
  const id = executeFunctions.getNodeParameter('id', itemIndex);
704
+ // Both catches below treat any failure as "not found".
705
+ await assertCredentials(executeFunctions);
898
706
  try {
899
707
  // First try to get by job ID
900
708
  try {
901
- await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
902
- method: 'GET',
903
- url: `${baseUrl}/api/job/${id}`,
904
- headers: {
905
- Accept: 'application/json',
906
- },
907
- });
709
+ await apiRequest(executeFunctions, 'GET', `/api/job/${id}`);
908
710
  // If we get here, the job exists by ID
909
711
  return { exists: true, found_by: 'job_id', id };
910
712
  }
911
713
  catch {
912
714
  // Job not found by ID, try searching by ext_id
913
- const searchResponse = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
914
- method: 'GET',
915
- url: `${baseUrl}/api/job`,
715
+ const searchResponse = await apiRequest(executeFunctions, 'GET', '/api/job', {
916
716
  qs: { ext_id: id },
917
- headers: {
918
- Accept: 'application/json',
919
- },
920
717
  });
921
718
  // Check if any results were returned
922
719
  const results = Array.isArray(searchResponse) ? searchResponse : [searchResponse];
@@ -936,109 +733,38 @@ class InNotes {
936
733
  message: `The operation "${operation}" is not supported for resource "job"!`,
937
734
  });
938
735
  }
939
- async executeStatusOperation(executeFunctions, itemIndex, operation) {
940
- const credentials = await executeFunctions.getCredentials('inNotesApi');
941
- const baseUrl = credentials.baseUrl;
736
+ static async executeStatusOperation(executeFunctions, itemIndex, operation) {
942
737
  if (operation === 'create') {
943
738
  const name = executeFunctions.getNodeParameter('name', itemIndex);
944
739
  const type = executeFunctions.getNodeParameter('type', itemIndex);
945
- const color = executeFunctions.getNodeParameter('color', itemIndex, '');
946
- const body = {
947
- name,
948
- type,
949
- ...(color && { color }),
950
- };
951
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
952
- method: 'POST',
953
- url: `${baseUrl}/api/statuses`,
954
- body,
955
- headers: {
956
- Accept: 'application/json',
957
- 'Content-Type': 'application/json',
958
- },
959
- });
960
- return response;
740
+ const body = { name, type };
741
+ return await apiRequest(executeFunctions, 'POST', '/api/statuses', { body });
961
742
  }
962
743
  if (operation === 'getAll') {
963
744
  const type = executeFunctions.getNodeParameter('type', itemIndex, 'contact');
964
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
965
- method: 'GET',
966
- url: `${baseUrl}/api/statuses`,
967
- qs: { type },
968
- headers: {
969
- Accept: 'application/json',
970
- },
971
- });
745
+ const response = await apiRequest(executeFunctions, 'GET', '/api/statuses', { qs: { type } });
972
746
  return Array.isArray(response) ? response : [response];
973
747
  }
974
- if (operation === 'update') {
975
- const statusId = executeFunctions.getNodeParameter('statusId', itemIndex);
976
- const updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);
977
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
978
- method: 'PUT',
979
- url: `${baseUrl}/api/statuses/${statusId}`,
980
- body: updateFields,
981
- headers: {
982
- Accept: 'application/json',
983
- 'Content-Type': 'application/json',
984
- },
985
- });
986
- return response;
987
- }
988
- if (operation === 'delete') {
989
- const statusId = executeFunctions.getNodeParameter('statusId', itemIndex);
990
- await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
991
- method: 'DELETE',
992
- url: `${baseUrl}/api/statuses/${statusId}`,
993
- headers: {
994
- Accept: 'application/json',
995
- },
996
- });
997
- return { success: true };
998
- }
999
748
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
1000
749
  message: `The operation "${operation}" is not supported for resource "status"!`,
1001
750
  });
1002
751
  }
1003
- async executeTagOperation(executeFunctions, _itemIndex, operation) {
1004
- const credentials = await executeFunctions.getCredentials('inNotesApi');
1005
- const baseUrl = credentials.baseUrl;
752
+ static async executeTagOperation(executeFunctions, _itemIndex, operation) {
1006
753
  if (operation === 'getAll') {
1007
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
1008
- method: 'GET',
1009
- url: `${baseUrl}/api/tags`,
1010
- headers: {
1011
- Accept: 'application/json',
1012
- },
1013
- });
754
+ const response = await apiRequest(executeFunctions, 'GET', '/api/tags');
1014
755
  return Array.isArray(response) ? response : [response];
1015
756
  }
1016
757
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
1017
758
  message: `The operation "${operation}" is not supported for resource "tag"! Supported operations: getAll`,
1018
759
  });
1019
760
  }
1020
- async executeUserOperation(executeFunctions, itemIndex, operation) {
761
+ static async executeUserOperation(executeFunctions, _itemIndex, operation) {
1021
762
  var _a, _b, _c, _d, _e, _f, _g;
1022
- const credentials = await executeFunctions.getCredentials('inNotesApi');
1023
- const baseUrl = credentials.baseUrl;
1024
763
  if (operation === 'get') {
1025
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
1026
- method: 'GET',
1027
- url: `${baseUrl}/api/user`,
1028
- headers: {
1029
- Accept: 'application/json',
1030
- },
1031
- });
1032
- return response;
764
+ return await apiRequest(executeFunctions, 'GET', '/api/user');
1033
765
  }
1034
766
  if (operation === 'getCv') {
1035
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
1036
- method: 'GET',
1037
- url: `${baseUrl}/api/user`,
1038
- headers: {
1039
- Accept: 'application/json',
1040
- },
1041
- });
767
+ const response = await apiRequest(executeFunctions, 'GET', '/api/user');
1042
768
  // Return only CV-related fields
1043
769
  const { cv, job_preferences, cv_updated_at } = response;
1044
770
  // Parse job_preferences if it's a JSON string
@@ -1082,21 +808,8 @@ class InNotes {
1082
808
  penalize: penalize.join(', '),
1083
809
  };
1084
810
  }
1085
- if (operation === 'update') {
1086
- const updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);
1087
- const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
1088
- method: 'PUT',
1089
- url: `${baseUrl}/api/user`,
1090
- body: updateFields,
1091
- headers: {
1092
- Accept: 'application/json',
1093
- 'Content-Type': 'application/json',
1094
- },
1095
- });
1096
- return response;
1097
- }
1098
811
  throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
1099
- message: `The operation "${operation}" is not supported for resource "user"! Supported operations: get, getCv, update`,
812
+ message: `The operation "${operation}" is not supported for resource "user"! Supported operations: get, getCv`,
1100
813
  });
1101
814
  }
1102
815
  }