@deepidealab/n8n-nodes-tracira 0.7.0 → 0.8.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.
Files changed (32) hide show
  1. package/README.md +11 -11
  2. package/dist/nodes/Tracira/Tracira.node.d.ts +8 -0
  3. package/dist/nodes/Tracira/Tracira.node.js +231 -99
  4. package/dist/nodes/Tracira/Tracira.node.js.map +1 -1
  5. package/dist/nodes/Tracira/listSearch/getProjects.d.ts +2 -0
  6. package/dist/nodes/Tracira/listSearch/{getFlows.js → getProjects.js} +8 -8
  7. package/dist/nodes/Tracira/listSearch/getProjects.js.map +1 -0
  8. package/dist/nodes/Tracira/listSearch/{getFlows.d.ts → getTasks.d.ts} +1 -1
  9. package/dist/nodes/Tracira/listSearch/getTasks.js +18 -0
  10. package/dist/nodes/Tracira/listSearch/getTasks.js.map +1 -0
  11. package/dist/package.json +2 -2
  12. package/dist/tsconfig.tsbuildinfo +1 -1
  13. package/package.json +2 -2
  14. package/dist/nodes/Tracira/listSearch/getChecks.d.ts +0 -2
  15. package/dist/nodes/Tracira/listSearch/getChecks.js +0 -18
  16. package/dist/nodes/Tracira/listSearch/getChecks.js.map +0 -1
  17. package/dist/nodes/Tracira/listSearch/getFlows.js.map +0 -1
  18. package/dist/nodes/Tracira/listSearch/getModels.d.ts +0 -2
  19. package/dist/nodes/Tracira/listSearch/getModels.js +0 -18
  20. package/dist/nodes/Tracira/listSearch/getModels.js.map +0 -1
  21. package/dist/nodes/Tracira/resources/execution/get.d.ts +0 -2
  22. package/dist/nodes/Tracira/resources/execution/get.js +0 -21
  23. package/dist/nodes/Tracira/resources/execution/get.js.map +0 -1
  24. package/dist/nodes/Tracira/resources/execution/getAll.d.ts +0 -2
  25. package/dist/nodes/Tracira/resources/execution/getAll.js +0 -244
  26. package/dist/nodes/Tracira/resources/execution/getAll.js.map +0 -1
  27. package/dist/nodes/Tracira/resources/execution/index.d.ts +0 -2
  28. package/dist/nodes/Tracira/resources/execution/index.js +0 -73
  29. package/dist/nodes/Tracira/resources/execution/index.js.map +0 -1
  30. package/dist/nodes/Tracira/resources/execution/log.d.ts +0 -2
  31. package/dist/nodes/Tracira/resources/execution/log.js +0 -291
  32. package/dist/nodes/Tracira/resources/execution/log.js.map +0 -1
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Tracira = void 0;
4
4
  const n8n_workflow_1 = require("n8n-workflow");
5
+ const getProjects_1 = require("./listSearch/getProjects");
6
+ const getTasks_1 = require("./listSearch/getTasks");
5
7
  const baseUrl = 'https://www.tracira.com/api';
6
8
  const logResourceDisplay = {
7
9
  resource: ['log'],
@@ -19,7 +21,7 @@ const getDisplay = {
19
21
  };
20
22
  const getAllDisplay = {
21
23
  resource: ['log'],
22
- operation: ['getAll'],
24
+ operation: ['search'],
23
25
  };
24
26
  const setDecisionDisplay = {
25
27
  resource: ['log'],
@@ -40,15 +42,15 @@ const apiCallDisplay = {
40
42
  function stripEmpty(data) {
41
43
  return Object.fromEntries(Object.entries(data).filter(([, value]) => value !== '' && value !== undefined && value !== null));
42
44
  }
43
- function normalizeApiPath(path) {
45
+ function normalizeApiPath(path, node) {
44
46
  if (!path.trim())
45
47
  return '/';
46
48
  if (path.startsWith('http://') || path.startsWith('https://')) {
47
- throw new n8n_workflow_1.ApplicationError('Use a path relative to https://www.tracira.com/api, for example /logs');
49
+ throw new n8n_workflow_1.NodeOperationError(node, 'Use a path relative to https://www.tracira.com/api, for example /logs');
48
50
  }
49
51
  return path.startsWith('/') ? path : `/${path}`;
50
52
  }
51
- function parseJsonObject(text, fieldName) {
53
+ function parseJsonObject(text, fieldName, node) {
52
54
  if (!text.trim())
53
55
  return {};
54
56
  let parsed;
@@ -56,10 +58,10 @@ function parseJsonObject(text, fieldName) {
56
58
  parsed = JSON.parse(text);
57
59
  }
58
60
  catch {
59
- throw new n8n_workflow_1.ApplicationError(`${fieldName} must be valid JSON`);
61
+ throw new n8n_workflow_1.NodeOperationError(node, `${fieldName} must be valid JSON`);
60
62
  }
61
63
  if (parsed === null || Array.isArray(parsed) || typeof parsed !== 'object') {
62
- throw new n8n_workflow_1.ApplicationError(`${fieldName} must be a JSON object`);
64
+ throw new n8n_workflow_1.NodeOperationError(node, `${fieldName} must be a JSON object`);
63
65
  }
64
66
  return parsed;
65
67
  }
@@ -86,7 +88,7 @@ class Tracira {
86
88
  this.description = {
87
89
  displayName: 'Tracira',
88
90
  name: 'tracira',
89
- icon: 'file:tracira.svg',
91
+ icon: { light: 'file:tracira.svg', dark: 'file:tracira.dark.svg' },
90
92
  group: ['transform'],
91
93
  version: 1,
92
94
  subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
@@ -110,8 +112,8 @@ class Tracira {
110
112
  defaults: {
111
113
  name: 'Tracira',
112
114
  },
113
- inputs: ['main'],
114
- outputs: ['main'],
115
+ inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
116
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
115
117
  credentials: [
116
118
  {
117
119
  name: 'traciraApi',
@@ -146,37 +148,37 @@ class Tracira {
146
148
  },
147
149
  options: [
148
150
  {
149
- name: 'Flag',
151
+ name: 'Create a Log',
152
+ value: 'log',
153
+ action: 'Create a log',
154
+ description: 'Send an AI output to Tracira and create a log for evaluation. Returns a verdict, confidence score, and explanation based on your configured rules.',
155
+ },
156
+ {
157
+ name: 'Flag a Log',
150
158
  value: 'flag',
151
- action: 'Flag a log for review',
159
+ action: 'Flag a log',
152
160
  description: 'Flag an evaluated log for human review, e.g. when an end-user reports an issue',
153
161
  },
154
162
  {
155
- name: 'Get',
163
+ name: 'Get a Log',
156
164
  value: 'get',
157
165
  action: 'Get a log',
158
- description: 'Fetch a single log by ID',
166
+ description: 'Fetch a single log by ID, including verdict, explanation, and human decision',
159
167
  },
160
168
  {
161
- name: 'Get Many',
162
- value: 'getAll',
163
- action: 'Get many logs',
164
- description: 'List logs from Tracira',
165
- },
166
- {
167
- name: 'Log',
168
- value: 'log',
169
- action: 'Log an AI output',
170
- description: 'Send an AI output to Tracira for evaluation',
169
+ name: 'Search Logs',
170
+ value: 'search',
171
+ action: 'Search logs',
172
+ description: 'Return a filtered list of logs from Tracira. Filter by status, project, task name, or date range.',
171
173
  },
172
174
  {
173
- name: 'Set Decision',
175
+ name: 'Set a Decision',
174
176
  value: 'setDecision',
175
- action: 'Set a decision for a log',
176
- description: 'Approve or reject a flagged log',
177
+ action: 'Set a decision',
178
+ description: 'Approve, reject, or send a flagged log back to the AI with a comment',
177
179
  },
178
180
  {
179
- name: 'Upload File',
181
+ name: 'Upload a File',
180
182
  value: 'upload',
181
183
  action: 'Upload a file',
182
184
  description: 'Upload a large file directly to Tracira storage, then attach it to a log by key',
@@ -235,20 +237,20 @@ class Tracira {
235
237
  },
236
238
  options: [
237
239
  {
238
- name: 'Approved',
240
+ name: 'Approve',
239
241
  value: 'approved',
240
242
  },
241
243
  {
242
- name: 'Changed',
243
- value: 'changed',
244
- description: 'Send the log back to the AI with a comment to regenerate',
244
+ name: 'Reject',
245
+ value: 'rejected',
245
246
  },
246
247
  {
247
- name: 'Rejected',
248
- value: 'rejected',
248
+ name: 'Send Back for Changes',
249
+ value: 'changed',
250
+ description: 'Send the log back to the AI with a comment to regenerate',
249
251
  },
250
252
  ],
251
- description: 'The human review decision to record',
253
+ description: 'Approve or reject the flagged log, or send it back to the AI with a comment',
252
254
  },
253
255
  {
254
256
  displayName: 'Comment',
@@ -265,7 +267,7 @@ class Tracira {
265
267
  decision: ['changed'],
266
268
  },
267
269
  },
268
- description: 'The instruction sent back to the AI describing what to change. Required when Decision is Changed. The AI should regenerate the output and resubmit it with the Log operation, setting Revision Of to this log ID.',
270
+ description: 'The instruction sent back to the AI describing what to change. Required when Decision is Send Back for Changes. The AI should regenerate the output and resubmit it with the Create a Log operation, setting Revision Of to this log ID.',
269
271
  },
270
272
  {
271
273
  displayName: 'Log ID',
@@ -314,18 +316,44 @@ class Tracira {
314
316
  description: 'Optional file name. Overrides the binary field name; its extension is used to detect the file type.',
315
317
  },
316
318
  {
317
- displayName: 'Project',
318
- name: 'projectName',
319
+ displayName: 'Content Type',
320
+ name: 'uploadContentType',
319
321
  type: 'string',
320
- required: true,
321
322
  default: '',
323
+ displayOptions: {
324
+ show: uploadDisplay,
325
+ },
326
+ description: 'Optional. Override the MIME type (e.g. application/pdf, image/png). Only needed when the file name has no recognizable extension.',
327
+ },
328
+ {
329
+ displayName: 'Project Name',
330
+ name: 'projectName',
331
+ type: 'resourceLocator',
332
+ required: true,
333
+ default: { mode: 'list', value: '' },
322
334
  displayOptions: {
323
335
  show: logOperationDisplay,
324
336
  },
325
- description: 'The Tracira project name for this log',
337
+ description: 'Select an existing project or enter a new name it will be auto-created in Tracira on first use',
338
+ modes: [
339
+ {
340
+ displayName: 'From List',
341
+ name: 'list',
342
+ type: 'list',
343
+ typeOptions: {
344
+ searchListMethod: 'getProjects',
345
+ searchable: true,
346
+ },
347
+ },
348
+ {
349
+ displayName: 'Name',
350
+ name: 'name',
351
+ type: 'string',
352
+ },
353
+ ],
326
354
  },
327
355
  {
328
- displayName: 'Output',
356
+ displayName: 'AI Output',
329
357
  name: 'output',
330
358
  type: 'string',
331
359
  typeOptions: {
@@ -336,10 +364,10 @@ class Tracira {
336
364
  displayOptions: {
337
365
  show: logOperationDisplay,
338
366
  },
339
- description: 'The AI-generated output to evaluate in Tracira',
367
+ description: 'The AI-generated output to evaluate against your Tracira rules',
340
368
  },
341
369
  {
342
- displayName: 'Input',
370
+ displayName: 'Text Prompt',
343
371
  name: 'input',
344
372
  type: 'string',
345
373
  typeOptions: {
@@ -349,7 +377,7 @@ class Tracira {
349
377
  displayOptions: {
350
378
  show: logOperationDisplay,
351
379
  },
352
- description: 'Optional prompt or input text that produced the output',
380
+ description: 'Optional text sent to your AI model alongside any attachments',
353
381
  },
354
382
  {
355
383
  displayName: 'Attachments',
@@ -363,23 +391,12 @@ class Tracira {
363
391
  displayOptions: {
364
392
  show: logOperationDisplay,
365
393
  },
366
- description: 'Files to attach to the log (the source the AI worked from)',
394
+ description: 'Files to attach to the log (the source the AI worked from). Tracira auto-detects whether each attachment is an image, audio file, or document.',
367
395
  options: [
368
396
  {
369
397
  name: 'attachment',
370
398
  displayName: 'Attachment',
371
399
  values: [
372
- {
373
- displayName: 'Source',
374
- name: 'source',
375
- type: 'options',
376
- default: 'uploaded',
377
- options: [
378
- { name: 'Uploaded File (Key)', value: 'uploaded' },
379
- { name: 'URL', value: 'url' },
380
- ],
381
- description: 'Where the file comes from',
382
- },
383
400
  {
384
401
  displayName: 'Attachment Key',
385
402
  name: 'key',
@@ -390,50 +407,103 @@ class Tracira {
390
407
  source: ['uploaded'],
391
408
  },
392
409
  },
393
- description: 'The key returned by an Upload File operation. Use this for large files (over 3 MB) that cannot be sent inline.',
410
+ description: 'The key returned by an Upload a File operation. Use this for large files (over 3 MB) that cannot be sent inline.',
394
411
  },
395
412
  {
396
- displayName: 'URL',
397
- name: 'url',
413
+ displayName: 'File Name',
414
+ name: 'filename',
398
415
  type: 'string',
399
416
  default: '',
417
+ description: 'Optional original file name shown to reviewers',
418
+ },
419
+ {
420
+ displayName: 'Input Binary Field',
421
+ name: 'binaryProperty',
422
+ type: 'string',
423
+ default: 'data',
400
424
  displayOptions: {
401
425
  show: {
402
- source: ['url'],
426
+ source: ['upload'],
403
427
  },
404
428
  },
405
- description: 'HTTPS URL to a publicly accessible image, audio file, or PDF',
429
+ hint: 'The name of the input field containing the binary file to attach',
430
+ description: 'The file is sent inline with this request. The whole request is limited to 4.5 MB, so keep inline files under ~3 MB. For larger files, use the Upload a File operation first, then attach with source "Tracira Upload".',
406
431
  },
407
432
  {
408
- displayName: 'File Name',
409
- name: 'filename',
433
+ displayName: 'Source',
434
+ name: 'source',
435
+ type: 'options',
436
+ default: 'upload',
437
+ options: [
438
+ {
439
+ name: 'From URL',
440
+ value: 'url',
441
+ description: 'HTTPS URL to a publicly accessible file',
442
+ },
443
+ {
444
+ name: 'Tracira Upload',
445
+ value: 'uploaded',
446
+ description: 'A key returned by the Upload a File operation — use for files over ~3 MB',
447
+ },
448
+ {
449
+ name: 'Upload File',
450
+ value: 'upload',
451
+ description: 'Send a binary file inline with this request (keep under ~3 MB)',
452
+ },
453
+ ],
454
+ description: 'Where the file comes from',
455
+ },
456
+ {
457
+ displayName: 'URL',
458
+ name: 'url',
410
459
  type: 'string',
411
460
  default: '',
412
- description: 'Optional original file name shown to reviewers',
461
+ displayOptions: {
462
+ show: {
463
+ source: ['url'],
464
+ },
465
+ },
466
+ description: 'HTTPS URL to a publicly accessible image, audio file, or PDF',
413
467
  },
414
468
  ],
415
469
  },
416
470
  ],
417
471
  },
418
472
  {
419
- displayName: 'Task',
473
+ displayName: 'Task Name',
420
474
  name: 'taskName',
421
- type: 'string',
422
- default: '',
475
+ type: 'resourceLocator',
476
+ default: { mode: 'list', value: '' },
423
477
  displayOptions: {
424
478
  show: logOperationDisplay,
425
479
  },
426
- description: 'Optional Tracira task name',
480
+ description: 'Optional. Select an existing task or enter a new name (e.g. "Tone Validator", "Reply Generator").',
481
+ modes: [
482
+ {
483
+ displayName: 'From List',
484
+ name: 'list',
485
+ type: 'list',
486
+ typeOptions: {
487
+ searchListMethod: 'getTasks',
488
+ searchable: true,
489
+ },
490
+ },
491
+ {
492
+ displayName: 'Name',
493
+ name: 'name',
494
+ type: 'string',
495
+ },
496
+ ],
427
497
  },
428
498
  {
429
- displayName: 'Model',
499
+ displayName: 'AI Model',
430
500
  name: 'modelName',
431
501
  type: 'string',
432
502
  default: '',
433
503
  displayOptions: {
434
504
  show: logOperationDisplay,
435
505
  },
436
- description: 'Optional AI model name to record with the log',
506
+ description: 'Optional. The name of the AI model that produced this output, exactly as you use it — e.g. "gpt-4o", "claude-sonnet-4-5".',
437
507
  },
438
508
  {
439
509
  displayName: 'Wait for Verdict',
@@ -562,24 +632,56 @@ class Tracira {
562
632
  description: 'Filter logs by status',
563
633
  },
564
634
  {
565
- displayName: 'Project',
635
+ displayName: 'Project Name',
566
636
  name: 'projectFilter',
567
- type: 'string',
568
- default: '',
637
+ type: 'resourceLocator',
638
+ default: { mode: 'list', value: '' },
569
639
  displayOptions: {
570
640
  show: getAllDisplay,
571
641
  },
572
- description: 'Filter logs to a specific project name',
642
+ description: 'Optional. Filter logs to a specific project name.',
643
+ modes: [
644
+ {
645
+ displayName: 'From List',
646
+ name: 'list',
647
+ type: 'list',
648
+ typeOptions: {
649
+ searchListMethod: 'getProjects',
650
+ searchable: true,
651
+ },
652
+ },
653
+ {
654
+ displayName: 'Name',
655
+ name: 'name',
656
+ type: 'string',
657
+ },
658
+ ],
573
659
  },
574
660
  {
575
- displayName: 'Task',
661
+ displayName: 'Task Name',
576
662
  name: 'taskFilter',
577
- type: 'string',
578
- default: '',
663
+ type: 'resourceLocator',
664
+ default: { mode: 'list', value: '' },
579
665
  displayOptions: {
580
666
  show: getAllDisplay,
581
667
  },
582
- description: 'Filter logs to a specific task name',
668
+ description: 'Optional. Filter logs to a specific task name within a project.',
669
+ modes: [
670
+ {
671
+ displayName: 'From List',
672
+ name: 'list',
673
+ type: 'list',
674
+ typeOptions: {
675
+ searchListMethod: 'getTasks',
676
+ searchable: true,
677
+ },
678
+ },
679
+ {
680
+ displayName: 'Name',
681
+ name: 'name',
682
+ type: 'string',
683
+ },
684
+ ],
583
685
  },
584
686
  {
585
687
  displayName: 'Search Query',
@@ -592,7 +694,7 @@ class Tracira {
592
694
  description: 'Search across project, task, model, and context IDs',
593
695
  },
594
696
  {
595
- displayName: 'From',
697
+ displayName: 'From Date',
596
698
  name: 'from',
597
699
  type: 'dateTime',
598
700
  default: '',
@@ -602,7 +704,7 @@ class Tracira {
602
704
  description: 'Only include logs at or after this date',
603
705
  },
604
706
  {
605
- displayName: 'To',
707
+ displayName: 'To Date',
606
708
  name: 'to',
607
709
  type: 'dateTime',
608
710
  default: '',
@@ -738,6 +840,12 @@ class Tracira {
738
840
  },
739
841
  ],
740
842
  };
843
+ this.methods = {
844
+ listSearch: {
845
+ getProjects: getProjects_1.getProjects,
846
+ getTasks: getTasks_1.getTasks,
847
+ },
848
+ };
741
849
  }
742
850
  async execute() {
743
851
  var _a, _b;
@@ -763,22 +871,41 @@ class Tracira {
763
871
  }
764
872
  const attachmentsParam = this.getNodeParameter('attachments', itemIndex, {});
765
873
  const attachmentRows = (_a = attachmentsParam.attachment) !== null && _a !== void 0 ? _a : [];
766
- const attachments = attachmentRows
767
- .map((row) => stripEmpty({
768
- source: row.source,
769
- key: row.key,
770
- url: row.url,
771
- filename: row.filename,
772
- }))
773
- .filter((row) => row.key !== undefined || row.url !== undefined);
874
+ const attachments = [];
875
+ for (const row of attachmentRows) {
876
+ if (row.source === 'upload') {
877
+ const binaryProperty = row.binaryProperty || 'data';
878
+ const binary = this.helpers.assertBinaryData(itemIndex, binaryProperty);
879
+ const buffer = await this.helpers.getBinaryDataBuffer(itemIndex, binaryProperty);
880
+ attachments.push(stripEmpty({
881
+ source: 'upload',
882
+ data: buffer.toString('base64'),
883
+ filename: row.filename || binary.fileName || 'file',
884
+ }));
885
+ continue;
886
+ }
887
+ const entry = stripEmpty({
888
+ source: row.source,
889
+ key: row.key,
890
+ url: row.url,
891
+ filename: row.filename,
892
+ });
893
+ if (entry.key !== undefined || entry.url !== undefined) {
894
+ attachments.push(entry);
895
+ }
896
+ }
774
897
  requestOptions = {
775
898
  method: 'POST',
776
899
  url: `${baseUrl}/logs`,
777
900
  body: stripEmpty({
778
- project: this.getNodeParameter('projectName', itemIndex),
901
+ project: this.getNodeParameter('projectName', itemIndex, '', {
902
+ extractValue: true,
903
+ }),
779
904
  output: this.getNodeParameter('output', itemIndex),
780
905
  input: this.getNodeParameter('input', itemIndex, ''),
781
- task: this.getNodeParameter('taskName', itemIndex, ''),
906
+ task: this.getNodeParameter('taskName', itemIndex, '', {
907
+ extractValue: true,
908
+ }),
782
909
  model: this.getNodeParameter('modelName', itemIndex, ''),
783
910
  attachments: attachments.length ? attachments : undefined,
784
911
  actorId: options.actorId,
@@ -804,15 +931,19 @@ class Tracira {
804
931
  url: `${baseUrl}/logs/${encodeURIComponent(logId)}`,
805
932
  };
806
933
  }
807
- else if (resource === 'log' && operation === 'getAll') {
934
+ else if (resource === 'log' && operation === 'search') {
808
935
  const filters = this.getNodeParameter('filters', itemIndex, {});
809
936
  requestOptions = {
810
937
  method: 'GET',
811
938
  url: `${baseUrl}/logs`,
812
939
  qs: stripEmpty({
813
940
  status: this.getNodeParameter('status', itemIndex, ''),
814
- project: this.getNodeParameter('projectFilter', itemIndex, ''),
815
- task: this.getNodeParameter('taskFilter', itemIndex, ''),
941
+ project: this.getNodeParameter('projectFilter', itemIndex, '', {
942
+ extractValue: true,
943
+ }),
944
+ task: this.getNodeParameter('taskFilter', itemIndex, '', {
945
+ extractValue: true,
946
+ }),
816
947
  q: this.getNodeParameter('query', itemIndex, ''),
817
948
  from: this.getNodeParameter('from', itemIndex, ''),
818
949
  to: this.getNodeParameter('to', itemIndex, ''),
@@ -831,7 +962,7 @@ class Tracira {
831
962
  ? this.getNodeParameter('comment', itemIndex, '')
832
963
  : '';
833
964
  if (decision === 'changed' && !comment.trim()) {
834
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Comment is required when Decision is Changed', { itemIndex });
965
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Comment is required when Decision is Send Back for Changes', { itemIndex });
835
966
  }
836
967
  requestOptions = {
837
968
  method: 'PATCH',
@@ -857,6 +988,7 @@ class Tracira {
857
988
  else if (resource === 'log' && operation === 'upload') {
858
989
  const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex, 'data');
859
990
  const fileNameOverride = this.getNodeParameter('uploadFileName', itemIndex, '');
991
+ const contentTypeOverride = this.getNodeParameter('uploadContentType', itemIndex, '');
860
992
  const binary = this.helpers.assertBinaryData(itemIndex, binaryPropertyName);
861
993
  const buffer = await this.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName);
862
994
  const filename = fileNameOverride || binary.fileName || 'file';
@@ -865,13 +997,13 @@ class Tracira {
865
997
  url: `${baseUrl}/uploads`,
866
998
  body: stripEmpty({
867
999
  filename,
868
- contentType: binary.mimeType,
1000
+ contentType: contentTypeOverride || binary.mimeType,
869
1001
  sizeBytes: buffer.length,
870
1002
  }),
871
1003
  }));
872
1004
  const uploadUrl = presign.uploadUrl;
873
1005
  const key = presign.key;
874
- const contentType = (_b = presign.contentType) !== null && _b !== void 0 ? _b : binary.mimeType;
1006
+ const contentType = (_b = presign.contentType) !== null && _b !== void 0 ? _b : (contentTypeOverride || binary.mimeType);
875
1007
  if (!uploadUrl || !key) {
876
1008
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Tracira did not return an upload URL', { itemIndex });
877
1009
  }
@@ -889,12 +1021,12 @@ class Tracira {
889
1021
  continue;
890
1022
  }
891
1023
  else if (resource === 'api' && operation === 'call') {
892
- const headers = parseJsonObject(this.getNodeParameter('apiHeadersJson', itemIndex, '{}'), 'Headers JSON');
893
- const qs = parseJsonObject(this.getNodeParameter('apiQueryJson', itemIndex, '{}'), 'Query String JSON');
1024
+ const headers = parseJsonObject(this.getNodeParameter('apiHeadersJson', itemIndex, '{}'), 'Headers JSON', this.getNode());
1025
+ const qs = parseJsonObject(this.getNodeParameter('apiQueryJson', itemIndex, '{}'), 'Query String JSON', this.getNode());
894
1026
  const body = parseOptionalJsonBody(this.getNodeParameter('apiBody', itemIndex, ''));
895
1027
  requestOptions = {
896
1028
  method: this.getNodeParameter('apiMethod', itemIndex),
897
- url: `${baseUrl}${normalizeApiPath(this.getNodeParameter('apiPath', itemIndex))}`,
1029
+ url: `${baseUrl}${normalizeApiPath(this.getNodeParameter('apiPath', itemIndex), this.getNode())}`,
898
1030
  headers,
899
1031
  qs,
900
1032
  body,
@@ -907,7 +1039,7 @@ class Tracira {
907
1039
  });
908
1040
  }
909
1041
  const response = await this.helpers.httpRequestWithAuthentication.call(this, 'traciraApi', requestOptions);
910
- if (resource === 'log' && operation === 'getAll' && Array.isArray(response === null || response === void 0 ? void 0 : response.executions)) {
1042
+ if (resource === 'log' && operation === 'search' && Array.isArray(response === null || response === void 0 ? void 0 : response.executions)) {
911
1043
  for (const log of response.executions) {
912
1044
  returnData.push({
913
1045
  json: log,