@limetech/n8n-nodes-lime 0.3.3 → 0.3.5

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 (51) hide show
  1. package/.github/workflows/mark-stale.yml +21 -0
  2. package/CHANGELOG.md +54 -0
  3. package/Dockerfile +2 -2
  4. package/dist/nodes/fortnox/resources/customers/operations/delete.operation.js +10 -1
  5. package/dist/nodes/fortnox/resources/customers/operations/delete.operation.js.map +1 -1
  6. package/dist/nodes/fortnox/resources/customers/operations/get.operation.js +10 -1
  7. package/dist/nodes/fortnox/resources/customers/operations/get.operation.js.map +1 -1
  8. package/dist/nodes/fortnox/resources/customers/operations/getAll.operation.js +1 -1
  9. package/dist/nodes/fortnox/resources/customers/operations/getAll.operation.js.map +1 -1
  10. package/dist/nodes/fortnox/resources/customers/operations/update.operation.js +10 -1
  11. package/dist/nodes/fortnox/resources/customers/operations/update.operation.js.map +1 -1
  12. package/dist/nodes/fortnox/resources/invoice/operations/get.operation.js +10 -1
  13. package/dist/nodes/fortnox/resources/invoice/operations/get.operation.js.map +1 -1
  14. package/dist/nodes/fortnox/resources/invoice/operations/getAll.operation.js +1 -1
  15. package/dist/nodes/fortnox/resources/invoice/operations/getAll.operation.js.map +1 -1
  16. package/dist/nodes/fortnox/resources/invoice/operations/update.operation.js +10 -1
  17. package/dist/nodes/fortnox/resources/invoice/operations/update.operation.js.map +1 -1
  18. package/dist/nodes/fortnox/transport/index.js +5 -0
  19. package/dist/nodes/fortnox/transport/index.js.map +1 -1
  20. package/dist/nodes/lime-crm/commons/webhook.d.ts +1 -0
  21. package/dist/nodes/lime-crm/commons/webhook.js +1 -0
  22. package/dist/nodes/lime-crm/commons/webhook.js.map +1 -1
  23. package/dist/nodes/lime-crm/resources/limeObject/operations/search.operation.js +18 -1
  24. package/dist/nodes/lime-crm/resources/limeObject/operations/search.operation.js.map +1 -1
  25. package/dist/nodes/lime-crm/transport/commons.d.ts +1 -1
  26. package/dist/nodes/lime-crm/transport/commons.js +1 -0
  27. package/dist/nodes/lime-crm/transport/commons.js.map +1 -1
  28. package/dist/nodes/lime-crm/transport/limeobjects.d.ts +5 -5
  29. package/dist/nodes/lime-crm/transport/limeobjects.js +106 -22
  30. package/dist/nodes/lime-crm/transport/limeobjects.js.map +1 -1
  31. package/dist/nodes/lime-crm/transport/limetypes.js +17 -2
  32. package/dist/nodes/lime-crm/transport/limetypes.js.map +1 -1
  33. package/dist/nodes/lime-crm/transport/webhooks.js +11 -1
  34. package/dist/nodes/lime-crm/transport/webhooks.js.map +1 -1
  35. package/dist/package.json +1 -1
  36. package/dist/tsconfig.tsbuildinfo +1 -1
  37. package/nodes/fortnox/resources/customers/operations/delete.operation.ts +11 -1
  38. package/nodes/fortnox/resources/customers/operations/get.operation.ts +11 -1
  39. package/nodes/fortnox/resources/customers/operations/getAll.operation.ts +1 -1
  40. package/nodes/fortnox/resources/customers/operations/update.operation.ts +11 -1
  41. package/nodes/fortnox/resources/invoice/operations/get.operation.ts +11 -1
  42. package/nodes/fortnox/resources/invoice/operations/getAll.operation.ts +1 -1
  43. package/nodes/fortnox/resources/invoice/operations/update.operation.ts +11 -1
  44. package/nodes/fortnox/transport/index.ts +5 -0
  45. package/nodes/lime-crm/commons/webhook.ts +2 -0
  46. package/nodes/lime-crm/resources/limeObject/operations/search.operation.ts +19 -6
  47. package/nodes/lime-crm/transport/commons.ts +2 -1
  48. package/nodes/lime-crm/transport/limeobjects.ts +141 -29
  49. package/nodes/lime-crm/transport/limetypes.ts +19 -2
  50. package/nodes/lime-crm/transport/webhooks.ts +12 -1
  51. package/package.json +2 -2
@@ -37,8 +37,18 @@ export async function execute(
37
37
  ) as string;
38
38
 
39
39
  const endpoint = `/customers/${encodeURIComponent(customerNumber)}`;
40
- return await apiRequest<null>(this, {
40
+ const response = await apiRequest<null>(this, {
41
41
  method: 'DELETE',
42
42
  endpoint,
43
43
  });
44
+
45
+ if (response.success) return response;
46
+
47
+ return {
48
+ ...response,
49
+ metadata: {
50
+ ...response.metadata,
51
+ id: customerNumber,
52
+ },
53
+ };
44
54
  }
@@ -38,8 +38,18 @@ export async function execute(
38
38
  ) as string;
39
39
 
40
40
  const endpoint = `/customers/${encodeURIComponent(customerNumber)}`;
41
- return await apiRequest<CustomerResponse>(this, {
41
+ const response = await apiRequest<CustomerResponse>(this, {
42
42
  method: 'GET',
43
43
  endpoint,
44
44
  });
45
+
46
+ if (response.success) return response;
47
+
48
+ return {
49
+ ...response,
50
+ metadata: {
51
+ ...response.metadata,
52
+ id: customerNumber,
53
+ },
54
+ };
45
55
  }
@@ -75,6 +75,6 @@ export async function execute(
75
75
  return await apiRequest<CustomersResponse>(this, {
76
76
  method: 'GET',
77
77
  endpoint: endpoint,
78
- qs,
78
+ qs: qs,
79
79
  });
80
80
  }
@@ -270,9 +270,19 @@ export async function execute(
270
270
 
271
271
  const endpoint = `/customers/${encodeURIComponent(customerNumber)}`;
272
272
 
273
- return await apiRequest<CustomerResponse>(this, {
273
+ const response = await apiRequest<CustomerResponse>(this, {
274
274
  method: 'PUT',
275
275
  endpoint: endpoint,
276
276
  body: body,
277
277
  });
278
+
279
+ if (response.success) return response;
280
+
281
+ return {
282
+ ...response,
283
+ metadata: {
284
+ ...response.metadata,
285
+ id: customerNumber,
286
+ },
287
+ };
278
288
  }
@@ -38,8 +38,18 @@ export async function execute(
38
38
 
39
39
  const endpoint = `invoices/${encodeURIComponent(documentNumber)}`;
40
40
 
41
- return await apiRequest<GetInvoiceResponse>(this, {
41
+ const response = await apiRequest<GetInvoiceResponse>(this, {
42
42
  method: 'GET',
43
43
  endpoint: endpoint,
44
44
  });
45
+
46
+ if (response.success) return response;
47
+
48
+ return {
49
+ ...response,
50
+ metadata: {
51
+ ...response.metadata,
52
+ id: documentNumber,
53
+ },
54
+ };
45
55
  }
@@ -96,6 +96,6 @@ export async function execute(
96
96
  return await apiRequest<GetAllInvoicesResponse>(this, {
97
97
  method: 'GET',
98
98
  endpoint: endpoint,
99
- qs,
99
+ qs: qs,
100
100
  });
101
101
  }
@@ -66,9 +66,19 @@ export async function execute(
66
66
 
67
67
  const endpoint = `invoices/${encodeURIComponent(documentNumber)}`;
68
68
 
69
- return await apiRequest<CreateInvoiceResponse>(this, {
69
+ const response = await apiRequest<CreateInvoiceResponse>(this, {
70
70
  method: 'PUT',
71
71
  endpoint: endpoint,
72
72
  body: body,
73
73
  });
74
+
75
+ if (response.success) return response;
76
+
77
+ return {
78
+ ...response,
79
+ metadata: {
80
+ ...response.metadata,
81
+ id: documentNumber,
82
+ },
83
+ };
74
84
  }
@@ -93,6 +93,11 @@ export async function apiRequest<T>(
93
93
  success: false,
94
94
  error: message,
95
95
  status: error?.cause?.status,
96
+ metadata: {
97
+ qs: options?.qs,
98
+ body: options?.body,
99
+ timeout: options?.timeout,
100
+ },
96
101
  };
97
102
  }
98
103
  }
@@ -14,6 +14,7 @@ export interface Webhook {
14
14
  events: string[];
15
15
  url?: string;
16
16
  context: WebhookContext;
17
+ name: string;
17
18
  }
18
19
 
19
20
  function _getEvents(hookData: WebhookFunctions): string[] {
@@ -46,5 +47,6 @@ export function getWebhook(hookData: WebhookFunctions): Webhook {
46
47
  events: _getEvents(hookData),
47
48
  url: hookData.getNodeWebhookUrl('default'),
48
49
  context: context,
50
+ name: hookData.getNodeParameter('name') as string,
49
51
  };
50
52
  }
@@ -27,8 +27,6 @@ export const properties: INodeProperties[] = [
27
27
  },
28
28
  },
29
29
  },
30
-
31
- // Search parameters
32
30
  {
33
31
  displayName: 'Search Term',
34
32
  name: 'searchTerm',
@@ -42,8 +40,6 @@ export const properties: INodeProperties[] = [
42
40
  },
43
41
  },
44
42
  },
45
-
46
- // Search fields
47
43
  {
48
44
  displayName: 'Search Fields',
49
45
  name: 'searchField',
@@ -62,7 +58,6 @@ export const properties: INodeProperties[] = [
62
58
  },
63
59
  },
64
60
  },
65
-
66
61
  {
67
62
  displayName: 'Limit',
68
63
  name: 'limit',
@@ -79,6 +74,22 @@ export const properties: INodeProperties[] = [
79
74
  },
80
75
  },
81
76
  },
77
+ {
78
+ displayName: 'Offset',
79
+ name: 'offset',
80
+ type: 'number',
81
+ default: 0,
82
+ description: 'Offset to first object to return',
83
+ typeOptions: {
84
+ minValue: 0,
85
+ },
86
+ displayOptions: {
87
+ show: {
88
+ resource: [LIMEOBJECT_RESOURCE],
89
+ operation: ['search'],
90
+ },
91
+ },
92
+ },
82
93
  ];
83
94
 
84
95
  export async function execute(this: IExecuteFunctions, i: number) {
@@ -86,6 +97,7 @@ export async function execute(this: IExecuteFunctions, i: number) {
86
97
  const searchTerm = this.getNodeParameter('searchTerm', i, '') as string;
87
98
  const searchField = this.getNodeParameter('searchField', i) as string;
88
99
  const limit = this.getNodeParameter('limit', i, 50);
100
+ const offset = this.getNodeParameter('offset', i, 0) as number;
89
101
  const options = this.getNodeParameter('options', i, {});
90
102
 
91
103
  return await searchLimeObject(
@@ -93,7 +105,8 @@ export async function execute(this: IExecuteFunctions, i: number) {
93
105
  limeType,
94
106
  searchField,
95
107
  searchTerm,
96
- limit || null,
108
+ limit,
109
+ offset,
97
110
  (options.sortField as string) || null
98
111
  );
99
112
  }
@@ -15,7 +15,7 @@ export async function callLimeApi<T>(
15
15
  nodeContext: IAllExecuteFunctions,
16
16
  method: HTTPMethod,
17
17
  url: string,
18
- options?: object
18
+ options?: Record<string, unknown>
19
19
  ): Promise<NodeResponse<T>> {
20
20
  try {
21
21
  const response: T =
@@ -39,6 +39,7 @@ export async function callLimeApi<T>(
39
39
  success: false,
40
40
  error: error instanceof Error ? error.message : String(error),
41
41
  status: error?.cause?.status,
42
+ metadata: options,
42
43
  };
43
44
  }
44
45
  }
@@ -1,5 +1,5 @@
1
1
  import { callLimeApi } from './commons';
2
- import { IAllExecuteFunctions } from 'n8n-workflow';
2
+ import { IAllExecuteFunctions, IDataObject } from 'n8n-workflow';
3
3
  import { NodeResponse } from '../../nodeResponse';
4
4
 
5
5
  const LIMEOBJECT_URL = '/api/v1/limeobject/';
@@ -12,66 +12,172 @@ interface SearchLimeobjectApiResponse {
12
12
 
13
13
  export async function createLimeObject(
14
14
  nodeContext: IAllExecuteFunctions,
15
- limetype: string,
15
+ limeType: string,
16
16
  data: object
17
17
  ): Promise<NodeResponse<unknown>> {
18
- const url = `${LIMEOBJECT_URL}${limetype}/`;
19
- return await callLimeApi(nodeContext, 'POST', url, {
18
+ const url = `${LIMEOBJECT_URL}${limeType}/`;
19
+ const response = await callLimeApi(nodeContext, 'POST', url, {
20
20
  body: data,
21
21
  });
22
+ if (response.success) return response;
23
+
24
+ return {
25
+ ...response,
26
+ metadata: {
27
+ ...response.metadata,
28
+ limeType: limeType,
29
+ },
30
+ };
22
31
  }
23
32
 
24
33
  export async function deleteLimeObject(
25
34
  nodeContext: IAllExecuteFunctions,
26
- limetype: string,
35
+ limeType: string,
27
36
  id: string
28
37
  ): Promise<NodeResponse<void>> {
29
- const url = `${LIMEOBJECT_URL}${limetype}/${id}/`;
30
- return await callLimeApi(nodeContext, 'DELETE', url);
38
+ const url = `${LIMEOBJECT_URL}${limeType}/${id}/`;
39
+ const response: NodeResponse<void> = await callLimeApi(
40
+ nodeContext,
41
+ 'DELETE',
42
+ url
43
+ );
44
+
45
+ if (response.success) return response;
46
+
47
+ return {
48
+ ...response,
49
+ metadata: {
50
+ ...response.metadata,
51
+ limeType: limeType,
52
+ id: id,
53
+ },
54
+ };
31
55
  }
32
56
 
33
57
  export async function getLimeObject(
34
58
  nodeContext: IAllExecuteFunctions,
35
- limetype: string,
59
+ limeType: string,
36
60
  id: string
37
61
  ): Promise<NodeResponse<unknown>> {
38
- const url = `${LIMEOBJECT_URL}${limetype}/${id}/`;
39
- return await callLimeApi(nodeContext, 'GET', url);
62
+ const url = `${LIMEOBJECT_URL}${limeType}/${id}/`;
63
+ const response = await callLimeApi(nodeContext, 'GET', url);
64
+
65
+ if (response.success) return response;
66
+
67
+ return {
68
+ ...response,
69
+ metadata: {
70
+ ...response.metadata,
71
+ limeType: limeType,
72
+ id: id,
73
+ },
74
+ };
40
75
  }
41
76
 
42
77
  export async function updateLimeObject(
43
78
  nodeContext: IAllExecuteFunctions,
44
- limetype: string,
79
+ limeType: string,
45
80
  id: string,
46
81
  data: object
47
82
  ): Promise<NodeResponse<unknown>> {
48
- const url = `${LIMEOBJECT_URL}${limetype}/${id}/`;
49
- return await callLimeApi(nodeContext, 'PUT', url, {
83
+ const url = `${LIMEOBJECT_URL}${limeType}/${id}/`;
84
+ const response = await callLimeApi(nodeContext, 'PUT', url, {
50
85
  body: data,
51
86
  });
87
+
88
+ if (response.success) return response;
89
+
90
+ return {
91
+ ...response,
92
+ metadata: {
93
+ ...response.metadata,
94
+ limeType: limeType,
95
+ id: id,
96
+ },
97
+ };
98
+ }
99
+
100
+ async function _searchLimeObjectWithLimit(
101
+ nodeContext: IAllExecuteFunctions,
102
+ url: string,
103
+ limit: number,
104
+ offset: number,
105
+ qs: IDataObject
106
+ ): Promise<NodeResponse<SearchLimeobjectApiResponse>> {
107
+ const returnData = [];
108
+ let hasMoreData = true;
109
+ let currentOffset = Math.max(0, offset);
110
+ const pageLimit = 50;
111
+
112
+ while (hasMoreData) {
113
+ qs._limit = Math.min(limit, pageLimit);
114
+ qs._offset = currentOffset;
115
+
116
+ const response = await callLimeApi<SearchLimeobjectApiResponse>(
117
+ nodeContext,
118
+ 'GET',
119
+ url,
120
+ {
121
+ qs: qs,
122
+ }
123
+ );
124
+ if (!response.success) return response;
125
+
126
+ const items = response.data._embedded?.limeobjects || [];
127
+
128
+ if (items.length === 0) {
129
+ hasMoreData = false;
130
+ } else {
131
+ returnData.push(...items);
132
+ currentOffset += items.length;
133
+ limit -= items.length;
134
+
135
+ if (limit <= 0) {
136
+ hasMoreData = false;
137
+ }
138
+ }
139
+ }
140
+ return {
141
+ success: true,
142
+ data: { _embedded: { limeobjects: returnData } },
143
+ };
52
144
  }
53
145
 
54
146
  export async function searchLimeObject(
55
147
  nodeContext: IAllExecuteFunctions,
56
- limetype: string,
148
+ limeType: string,
57
149
  searchField: string,
58
150
  searchTerm: string,
59
- limit: number | null,
151
+ limit: number,
152
+ offset: number,
60
153
  sortField: string | null
61
154
  ): Promise<NodeResponse<Array<object>>> {
62
- const url = `${LIMEOBJECT_URL}${limetype}/`;
63
- const response = await callLimeApi<SearchLimeobjectApiResponse>(
64
- nodeContext,
65
- 'GET',
66
- url,
67
- {
68
- qs: {
69
- ...(searchField && searchTerm && { [searchField]: searchTerm }),
70
- ...(limit != null && limit > 0 && { _limit: limit }),
71
- ...(sortField != null && { _sort: sortField }),
72
- },
73
- }
74
- );
155
+ const url = `${LIMEOBJECT_URL}${limeType}/`;
156
+ const qs: IDataObject = {
157
+ ...(searchField && searchTerm && { [searchField]: searchTerm }),
158
+ ...(offset != null && offset > 0 && { _offset: offset }),
159
+ ...(sortField != null && { _sort: sortField }),
160
+ };
161
+
162
+ let response;
163
+ if (limit) {
164
+ response = await _searchLimeObjectWithLimit(
165
+ nodeContext,
166
+ url,
167
+ limit,
168
+ offset,
169
+ qs
170
+ );
171
+ } else {
172
+ response = await callLimeApi<SearchLimeobjectApiResponse>(
173
+ nodeContext,
174
+ 'GET',
175
+ url,
176
+ {
177
+ qs: qs,
178
+ }
179
+ );
180
+ }
75
181
 
76
182
  if (response.success) {
77
183
  return {
@@ -79,5 +185,11 @@ export async function searchLimeObject(
79
185
  data: response.data?._embedded.limeobjects ?? [],
80
186
  };
81
187
  }
82
- return response;
188
+ return {
189
+ ...response,
190
+ metadata: {
191
+ ...response.metadata,
192
+ limeType: limeType,
193
+ },
194
+ };
83
195
  }
@@ -39,7 +39,17 @@ export async function getLimeType(
39
39
  limeType: string
40
40
  ): Promise<NodeResponse<LimeType>> {
41
41
  const url = `${LIMETYPE_URL}${limeType}/`;
42
- return await callLimeApi<LimeType>(nodeContext, 'GET', url);
42
+ const response = await callLimeApi<LimeType>(nodeContext, 'GET', url);
43
+
44
+ if (response.success) return response;
45
+
46
+ return {
47
+ ...response,
48
+ metadata: {
49
+ ...response.metadata,
50
+ limetype: limeType,
51
+ },
52
+ };
43
53
  }
44
54
 
45
55
  export async function getProperties(
@@ -64,5 +74,12 @@ export async function getProperties(
64
74
  data: response.data?._embedded.properties ?? [],
65
75
  };
66
76
  }
67
- return response;
77
+
78
+ return {
79
+ ...response,
80
+ metadata: {
81
+ ...response.metadata,
82
+ limetype: limeType,
83
+ },
84
+ };
68
85
  }
@@ -45,6 +45,7 @@ export async function createSubscription(
45
45
  body: {
46
46
  events: webhook.events,
47
47
  target_url: webhook.url,
48
+ name: webhook.name,
48
49
  },
49
50
  });
50
51
  }
@@ -53,9 +54,19 @@ export async function deleteSubscription(
53
54
  nodeContext: IAllExecuteFunctions,
54
55
  webhook: Webhook
55
56
  ): Promise<NodeResponse<void>> {
56
- return await callLimeApi(
57
+ const response: NodeResponse<void> = await callLimeApi(
57
58
  nodeContext,
58
59
  'DELETE',
59
60
  `${SUBSCRIPTION_URL}${webhook.data.webhookId}/`
60
61
  );
62
+
63
+ if (response.success) return response;
64
+
65
+ return {
66
+ ...response,
67
+ metadata: {
68
+ ...response.metadata,
69
+ id: webhook.data.webhookId,
70
+ },
71
+ };
61
72
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@limetech/n8n-nodes-lime",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "n8n node to connect to Lime CRM",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -29,7 +29,7 @@
29
29
  "dist/credentials/FortnoxApi.credentials.js"
30
30
  ],
31
31
  "nodes": [
32
- "dist/nodes/lime-crm/LimeCrm.node.js",
32
+ "dist/nodes/lime-crm/LimeCrmNode.node.js",
33
33
  "dist/nodes/fortnox/Fortnox.node.js",
34
34
  "dist/nodes/fortnox/FortnoxTrigger.node.js"
35
35
  ]