n8n-nodes-mautic-advanced 0.1.9 → 0.2.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.
@@ -510,10 +510,9 @@ exports.companyFields = [
510
510
  },
511
511
  typeOptions: {
512
512
  minValue: 1,
513
- maxValue: 30,
514
513
  },
515
514
  default: 30,
516
- description: 'Max number of results to return',
515
+ description: 'Max number of results to return. If you request more than 30 records, the node will automatically use pagination to fetch up to the requested number.',
517
516
  },
518
517
  {
519
518
  displayName: 'Simplify',
@@ -1295,10 +1295,9 @@ exports.contactFields = [
1295
1295
  },
1296
1296
  typeOptions: {
1297
1297
  minValue: 1,
1298
- maxValue: 30,
1299
1298
  },
1300
1299
  default: 30,
1301
- description: 'Max number of results to return',
1300
+ description: 'Max number of results to return. If you request more than 30 records, the node will automatically use pagination to fetch up to the requested number.',
1302
1301
  },
1303
1302
  /* -------------------------------------------------------------------------- */
1304
1303
  /* contact:delete */
@@ -43,54 +43,26 @@ exports.mauticApiRequest = mauticApiRequest;
43
43
  * Make an API request to paginated mautic endpoint
44
44
  * and return all results
45
45
  */
46
- async function mauticApiRequestAllItems(propertyName, method, endpoint, body = {}, query = {}) {
46
+ async function mauticApiRequestAllItems(propertyName, method, endpoint, body = {}, query = {}, maxResults) {
47
47
  const returnData = [];
48
48
  let responseData;
49
49
  query.limit = 30;
50
50
  query.start = 0;
51
- let page = 0;
51
+ // Removed unused 'page' variable
52
52
  do {
53
53
  responseData = await mauticApiRequest.call(this, method, endpoint, body, query);
54
54
  const values = Object.values(responseData[propertyName]);
55
- // Log per-page
56
- const pageIds = values.map(v => {
57
- if (typeof v === 'object' && v !== null) {
58
- const obj = v;
59
- return obj.id ?? (obj.fields && obj.fields.id);
60
- }
61
- return undefined;
62
- });
63
- console.log(`[DEBUG] Page ${page} (start=${query.start}, limit=${query.limit}): IDs =`, pageIds);
64
- returnData.push.apply(returnData, values);
65
- query.start += query.limit;
66
- page++;
67
- } while (responseData.total !== undefined &&
68
- returnData.length - parseInt(responseData.total, 10) < 0);
69
- // Log all IDs before deduplication
70
- const allIds = returnData.map(item => {
71
- if (typeof item === 'object' && item !== null) {
72
- const obj = item;
73
- return obj.id ?? (obj.fields && obj.fields.id);
55
+ if (maxResults !== undefined && returnData.length + values.length > maxResults) {
56
+ const needed = maxResults - returnData.length;
57
+ returnData.push(...values.slice(0, needed));
58
+ break;
74
59
  }
75
- return undefined;
76
- });
77
- console.log('[DEBUG] All IDs before deduplication:', allIds);
78
- // Log duplicates
79
- const filteredIds = allIds.filter(id => typeof id === 'string' || typeof id === 'number');
80
- const idCounts = filteredIds.reduce((acc, id) => {
81
- const key = String(id);
82
- acc[key] = (acc[key] || 0) + 1;
83
- return acc;
84
- }, {});
85
- const duplicates = Object.entries(idCounts).filter(([_, count]) => count > 1);
86
- if (duplicates.length > 0) {
87
- console.log('[DEBUG] Duplicate IDs found:', duplicates);
88
- }
89
- else {
90
- console.log('[DEBUG] No duplicate IDs found.');
91
- }
92
- // Log summary
93
- console.log(`[DEBUG] Total records fetched: ${returnData.length}`);
60
+ else {
61
+ returnData.push(...values);
62
+ }
63
+ query.start += query.limit;
64
+ } while ((responseData.total !== undefined && returnData.length - parseInt(responseData.total, 10) < 0) &&
65
+ (maxResults === undefined || returnData.length < maxResults));
94
66
  return returnData;
95
67
  }
96
68
  exports.mauticApiRequestAllItems = mauticApiRequestAllItems;
@@ -803,23 +803,26 @@ class MauticAdvanced {
803
803
  const options = this.getNodeParameter('options', i);
804
804
  qs = Object.assign(qs, options);
805
805
  if (qs.orderBy) {
806
- // For some reason does camelCase get used in the returned data
807
- // but snake_case here. So convert it automatically to not confuse
808
- // the users.
809
806
  qs.orderBy = (0, change_case_1.snakeCase)(qs.orderBy);
810
807
  }
811
808
  if (returnAll) {
812
809
  responseData = await GenericFunctions_1.mauticApiRequestAllItems.call(this, 'contacts', 'GET', '/contacts', {}, qs);
813
810
  }
814
811
  else {
815
- qs.limit = this.getNodeParameter('limit', i);
816
- qs.start = 0;
817
- responseData = await GenericFunctions_1.mauticApiRequest.call(this, 'GET', '/contacts', {}, qs);
818
- if (responseData.errors) {
819
- throw new n8n_workflow_1.NodeApiError(this.getNode(), responseData);
812
+ const limit = this.getNodeParameter('limit', i);
813
+ if (limit > 30) {
814
+ responseData = await GenericFunctions_1.mauticApiRequestAllItems.call(this, 'contacts', 'GET', '/contacts', {}, qs, limit);
815
+ }
816
+ else {
817
+ qs.limit = limit;
818
+ qs.start = 0;
819
+ responseData = await GenericFunctions_1.mauticApiRequest.call(this, 'GET', '/contacts', {}, qs);
820
+ if (responseData.errors) {
821
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), responseData);
822
+ }
823
+ responseData = responseData.contacts;
824
+ responseData = Object.values(responseData);
820
825
  }
821
- responseData = responseData.contacts;
822
- responseData = Object.values(responseData);
823
826
  }
824
827
  if (options.rawData === false) {
825
828
  //@ts-ignore
@@ -832,8 +835,6 @@ class MauticAdvanced {
832
835
  const contactId = this.getNodeParameter('contactId', i);
833
836
  try {
834
837
  responseData = await GenericFunctions_1.mauticApiRequest.call(this, 'DELETE', `/contacts/${contactId}/delete`);
835
- // Debug: log raw response from mauticApiRequest
836
- console.log('[DEBUG] mauticApiRequest response for contact delete:', JSON.stringify(responseData, null, 2));
837
838
  // Mautic API may return 200 with no 'contact' property or empty body on successful delete
838
839
  if (responseData && responseData.contact !== undefined) {
839
840
  responseData = [responseData.contact];
@@ -844,8 +845,6 @@ class MauticAdvanced {
844
845
  }
845
846
  }
846
847
  catch (error) {
847
- // Debug: log error object
848
- console.log('[DEBUG] Error caught in contact delete operation:', JSON.stringify(error, Object.getOwnPropertyNames(error), 2));
849
848
  // If the error is a 404 (not found), treat as successful delete (idempotent)
850
849
  if (error instanceof n8n_workflow_1.NodeApiError && error.httpCode === '404') {
851
850
  responseData = [{ success: true, message: 'Contact already deleted or not found.' }];
@@ -854,8 +853,6 @@ class MauticAdvanced {
854
853
  throw error;
855
854
  }
856
855
  }
857
- // Debug: log final responseData before returning
858
- console.log('[DEBUG] Final responseData to return from contact delete:', JSON.stringify(responseData, null, 2));
859
856
  if (options.rawData === false) {
860
857
  responseData = responseData.map((item) => item.fields?.all ?? item);
861
858
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-mautic-advanced",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "description": "Enhanced n8n node for Mautic with comprehensive API coverage including tags, campaigns, categories, and advanced contact management",
5
5
  "keywords": [
6
6
  "n8n",