@limetech/n8n-nodes-lime 0.2.8 → 0.3.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 (88) hide show
  1. package/.dockerignore +1 -0
  2. package/.github/workflows/lint.yml +21 -0
  3. package/.github/workflows/release.yml +82 -0
  4. package/.github/workflows/test-and-build.yml +47 -0
  5. package/.prettierignore +4 -0
  6. package/.prettierrc.mjs +1 -0
  7. package/.releaserc.json +34 -0
  8. package/CHANGELOG.md +74 -0
  9. package/Dockerfile +21 -0
  10. package/README.md +4 -0
  11. package/credentials/FortnoxApi.credentials.ts +61 -0
  12. package/credentials/LimeCrmApi.credentials.ts +60 -0
  13. package/dist/nodes/LimeCrm/resources/limeObject/operations/update.operation.js +1 -1
  14. package/dist/nodes/LimeCrm/resources/limeObject/operations/update.operation.js.map +1 -1
  15. package/dist/package.json +1 -1
  16. package/dist/tsconfig.tsbuildinfo +1 -1
  17. package/docker-compose.yml +46 -0
  18. package/eslint.config.mjs +27 -0
  19. package/jest.config.js +11 -0
  20. package/nodes/fortnox/Fortnox.node.json +18 -0
  21. package/nodes/fortnox/Fortnox.node.ts +102 -0
  22. package/nodes/fortnox/FortnoxTrigger.node.json +18 -0
  23. package/nodes/fortnox/FortnoxTrigger.node.ts +196 -0
  24. package/nodes/fortnox/commons.ts +94 -0
  25. package/nodes/fortnox/fortnoxLogo.svg +15 -0
  26. package/nodes/fortnox/model.ts +25 -0
  27. package/nodes/fortnox/resources/customers/filterParameters.ts +47 -0
  28. package/nodes/fortnox/resources/customers/index.ts +57 -0
  29. package/nodes/fortnox/resources/customers/model.ts +107 -0
  30. package/nodes/fortnox/resources/customers/operations/create.operation.ts +303 -0
  31. package/nodes/fortnox/resources/customers/operations/delete.operation.ts +44 -0
  32. package/nodes/fortnox/resources/customers/operations/get.operation.ts +45 -0
  33. package/nodes/fortnox/resources/customers/operations/getAll.operation.ts +80 -0
  34. package/nodes/fortnox/resources/customers/operations/update.operation.ts +278 -0
  35. package/nodes/fortnox/resources/customers/sortParameters.ts +32 -0
  36. package/nodes/fortnox/resources/invoice/filterParameters.ts +88 -0
  37. package/nodes/fortnox/resources/invoice/index.ts +51 -0
  38. package/nodes/fortnox/resources/invoice/invoiceParameters.ts +214 -0
  39. package/nodes/fortnox/resources/invoice/model.ts +160 -0
  40. package/nodes/fortnox/resources/invoice/operations/create.operation.ts +72 -0
  41. package/nodes/fortnox/resources/invoice/operations/get.operation.ts +45 -0
  42. package/nodes/fortnox/resources/invoice/operations/getAll.operation.ts +101 -0
  43. package/nodes/fortnox/resources/invoice/operations/update.operation.ts +74 -0
  44. package/nodes/fortnox/transport/errorCodes.ts +62 -0
  45. package/nodes/fortnox/transport/index.ts +98 -0
  46. package/nodes/lime-crm/LimeCrm.node.json +18 -0
  47. package/nodes/lime-crm/LimeCrmNode.node.ts +135 -0
  48. package/nodes/lime-crm/LimeCrmTrigger.node.ts +263 -0
  49. package/nodes/lime-crm/assets/lime-crm.svg +1 -0
  50. package/nodes/lime-crm/commons/constants.ts +9 -0
  51. package/nodes/lime-crm/commons/index.ts +9 -0
  52. package/nodes/lime-crm/commons/limetype.ts +11 -0
  53. package/nodes/lime-crm/commons/task.ts +55 -0
  54. package/nodes/lime-crm/commons/webhook.ts +50 -0
  55. package/nodes/lime-crm/methods/getEntitiesForErpSystem.ts +11 -0
  56. package/nodes/lime-crm/methods/getLimeTypeProperties.ts +27 -0
  57. package/nodes/lime-crm/methods/getLimeTypes.ts +23 -0
  58. package/nodes/lime-crm/methods/index.ts +3 -0
  59. package/nodes/lime-crm/resources/erpConnector/index.ts +43 -0
  60. package/nodes/lime-crm/resources/erpConnector/operations/createOrUpdateObjects.operation.ts +69 -0
  61. package/nodes/lime-crm/resources/erpConnector/operations/transform.operation.ts +274 -0
  62. package/nodes/lime-crm/resources/erpConnector/transform.ts +49 -0
  63. package/nodes/lime-crm/resources/erpConnector/transformers/baseTransformer.ts +18 -0
  64. package/nodes/lime-crm/resources/erpConnector/transformers/fortnox.ts +201 -0
  65. package/nodes/lime-crm/resources/erpConnector/transformers/index.ts +1 -0
  66. package/nodes/lime-crm/resources/limeObject/index.ts +64 -0
  67. package/nodes/lime-crm/resources/limeObject/operations/create.operation.ts +152 -0
  68. package/nodes/lime-crm/resources/limeObject/operations/delete.operation.ts +55 -0
  69. package/nodes/lime-crm/resources/limeObject/operations/get.operation.ts +54 -0
  70. package/nodes/lime-crm/resources/limeObject/operations/search.operation.ts +99 -0
  71. package/nodes/lime-crm/resources/limeObject/operations/update.operation.ts +157 -0
  72. package/nodes/lime-crm/resources/limeType/index.ts +58 -0
  73. package/nodes/lime-crm/resources/limeType/operations/getProperties.operation.ts +42 -0
  74. package/nodes/lime-crm/resources/limeType/operations/getType.operation.ts +36 -0
  75. package/nodes/lime-crm/resources/limeType/operations/listTypes.operation.ts +18 -0
  76. package/nodes/lime-crm/transport/commons.ts +44 -0
  77. package/nodes/lime-crm/transport/erpConnector.ts +21 -0
  78. package/nodes/lime-crm/transport/index.ts +17 -0
  79. package/nodes/lime-crm/transport/limeobjects.ts +83 -0
  80. package/nodes/lime-crm/transport/limetypes.ts +68 -0
  81. package/nodes/lime-crm/transport/task.ts +32 -0
  82. package/nodes/lime-crm/transport/webhooks.ts +61 -0
  83. package/nodes/nodeResponse.ts +13 -0
  84. package/package.json +36 -16
  85. package/tests/fixtures/fortnox.ts +182 -0
  86. package/tests/transform.spec.ts +187 -0
  87. package/tsconfig.json +30 -0
  88. package/index.js +0 -3
@@ -0,0 +1,303 @@
1
+ import { IExecuteFunctions, INodeProperties, IDataObject } from 'n8n-workflow';
2
+ import { apiRequest } from '../../../transport';
3
+ import { code as currencyCode } from 'currency-codes';
4
+ import { CustomerResponse } from '../model';
5
+ import { NodeResponse } from '../../../../nodeResponse';
6
+
7
+ export const description = {
8
+ name: 'Create Customer',
9
+ value: 'create',
10
+ description: 'Create a new customer',
11
+ action: 'Create a customer',
12
+ };
13
+
14
+ export const createProperties: INodeProperties[] = [
15
+ {
16
+ displayName: 'Address 1',
17
+ name: 'Address1',
18
+ type: 'string',
19
+ default: '',
20
+ description: "Customer's primary address",
21
+ },
22
+ {
23
+ displayName: 'Address 2',
24
+ name: 'Address2',
25
+ type: 'string',
26
+ default: '',
27
+ description: "Customer's secondary address",
28
+ },
29
+ {
30
+ displayName: 'City',
31
+ name: 'City',
32
+ type: 'string',
33
+ default: '',
34
+ description: "Customer's city",
35
+ },
36
+ {
37
+ displayName: 'Comments',
38
+ name: 'Comments',
39
+ type: 'string',
40
+ default: '',
41
+ description: 'Comments about the customer',
42
+ },
43
+ {
44
+ displayName: 'Cost Center',
45
+ name: 'CostCenter',
46
+ type: 'string',
47
+ default: '',
48
+ description: "Customer's cost center",
49
+ },
50
+ {
51
+ displayName: 'Country',
52
+ name: 'Country',
53
+ type: 'string',
54
+ default: '',
55
+ description: "Customer's country",
56
+ },
57
+ {
58
+ displayName: 'Country Code',
59
+ name: 'CountryCode',
60
+ type: 'string',
61
+ default: '',
62
+ description: "Customer's country code",
63
+ },
64
+ {
65
+ displayName: 'Email',
66
+ name: 'Email',
67
+ type: 'string',
68
+ default: '',
69
+ description: "Customer's email address",
70
+ },
71
+ {
72
+ displayName: 'External Reference',
73
+ name: 'ExternalReference',
74
+ type: 'string',
75
+ default: '',
76
+ description: 'External reference for the customer',
77
+ },
78
+ {
79
+ displayName: 'Fax',
80
+ name: 'Fax',
81
+ type: 'string',
82
+ default: '',
83
+ description: "Customer's fax number",
84
+ },
85
+ {
86
+ displayName: 'GLN',
87
+ name: 'GLN',
88
+ type: 'string',
89
+ default: '',
90
+ description: 'Global Location Number',
91
+ },
92
+ {
93
+ displayName: 'Organisation Number',
94
+ name: 'OrganisationNumber',
95
+ type: 'string',
96
+ default: '',
97
+ description: "Customer's organisation number",
98
+ },
99
+ {
100
+ displayName: 'Phone 1',
101
+ name: 'Phone1',
102
+ type: 'string',
103
+ default: '',
104
+ description: "Customer's primary phone number",
105
+ },
106
+ {
107
+ displayName: 'Phone 2',
108
+ name: 'Phone2',
109
+ type: 'string',
110
+ default: '',
111
+ description: "Customer's secondary phone number",
112
+ },
113
+ {
114
+ displayName: 'VAT Number',
115
+ name: 'VATNumber',
116
+ type: 'string',
117
+ default: '',
118
+ description: "Customer's VAT number",
119
+ },
120
+ {
121
+ displayName: 'Website',
122
+ name: 'WWW',
123
+ type: 'string',
124
+ default: '',
125
+ description: "Customer's website URL",
126
+ },
127
+ {
128
+ displayName: 'ZIP Code',
129
+ name: 'ZipCode',
130
+ type: 'string',
131
+ default: '',
132
+ description: "Customer's ZIP/postal code",
133
+ },
134
+ ];
135
+
136
+ export const properties: INodeProperties[] = [
137
+ {
138
+ displayName: 'Name',
139
+ name: 'Name',
140
+ type: 'string',
141
+ required: true,
142
+ default: '',
143
+ description: 'Customer name',
144
+ displayOptions: {
145
+ show: {
146
+ resource: ['customer'],
147
+ operation: ['create'],
148
+ },
149
+ },
150
+ },
151
+ {
152
+ displayName: 'Active',
153
+ name: 'Active',
154
+ type: 'boolean',
155
+ required: true,
156
+ default: true,
157
+ description: 'Whether the customer is active',
158
+ displayOptions: {
159
+ show: {
160
+ resource: ['customer'],
161
+ operation: ['create'],
162
+ },
163
+ },
164
+ },
165
+ {
166
+ displayName: 'Currency',
167
+ name: 'Currency',
168
+ type: 'string',
169
+ required: true,
170
+ default: 'SEK',
171
+ description: 'Currency',
172
+ displayOptions: {
173
+ show: {
174
+ resource: ['customer'],
175
+ operation: ['create'],
176
+ },
177
+ },
178
+ },
179
+ {
180
+ displayName: 'Type',
181
+ name: 'Type',
182
+ type: 'options',
183
+ required: true,
184
+ options: [
185
+ {
186
+ name: 'Private',
187
+ value: 'PRIVATE',
188
+ },
189
+ {
190
+ name: 'Company',
191
+ value: 'COMPANY',
192
+ },
193
+ ],
194
+ default: 'COMPANY',
195
+ description: 'Type of customer',
196
+ displayOptions: {
197
+ show: {
198
+ resource: ['customer'],
199
+ operation: ['create'],
200
+ },
201
+ },
202
+ },
203
+ {
204
+ displayName: 'VAT Type',
205
+ name: 'VATType',
206
+ type: 'options',
207
+ required: true,
208
+
209
+ options: [
210
+ {
211
+ name: 'SE VAT',
212
+ value: 'SEVAT',
213
+ },
214
+ {
215
+ name: 'SE Reversed VAT',
216
+ value: 'SEREVERSEDVAT',
217
+ },
218
+ {
219
+ name: 'EU Reversed VAT',
220
+ value: 'EUREVERSEDVAT',
221
+ },
222
+ {
223
+ name: 'EU VAT',
224
+ value: 'EUVAT',
225
+ },
226
+ {
227
+ name: 'Export',
228
+ value: 'EXPORT',
229
+ },
230
+ ],
231
+ default: 'SEVAT',
232
+ description: 'Type of VAT applied',
233
+ displayOptions: {
234
+ show: {
235
+ resource: ['customer'],
236
+ operation: ['create'],
237
+ },
238
+ },
239
+ },
240
+ // Additional Fields
241
+ {
242
+ displayName: 'Additional Fields',
243
+ name: 'additionalFields',
244
+ type: 'collection',
245
+ placeholder: 'Add Field',
246
+ default: {},
247
+ displayOptions: {
248
+ show: {
249
+ resource: ['customer'],
250
+ operation: ['create'],
251
+ },
252
+ },
253
+ options: [...createProperties],
254
+ },
255
+ ];
256
+
257
+ export async function execute(
258
+ this: IExecuteFunctions,
259
+ i: number
260
+ ): Promise<NodeResponse<CustomerResponse>> {
261
+ const name = this.getNodeParameter('Name', i) as string;
262
+ let currency = this.getNodeParameter('Currency', i) as string;
263
+ currency = currency.toUpperCase();
264
+ const active = this.getNodeParameter('Active', i) as boolean;
265
+ const type = this.getNodeParameter('Type', i) as 'COMPANY' | 'PRIVATE';
266
+ const vatType = this.getNodeParameter('VATType', i) as
267
+ | 'SEVAT'
268
+ | 'SEREVERSEDVAT'
269
+ | 'EUREVERSEDVAT'
270
+ | 'EUVAT'
271
+ | 'EXPORT';
272
+ const additionalFields = this.getNodeParameter(
273
+ 'additionalFields',
274
+ i,
275
+ {}
276
+ ) as IDataObject;
277
+
278
+ if (currencyCode(currency) === undefined) {
279
+ return {
280
+ success: false,
281
+ error: `Invalid currency code: ${currency}. Use ISO 4217 currency code.`,
282
+ };
283
+ }
284
+
285
+ const body = {
286
+ Customer: {
287
+ Name: name,
288
+ Currency: currency,
289
+ Active: active,
290
+ Type: type,
291
+ VATType: vatType,
292
+ ...additionalFields,
293
+ },
294
+ };
295
+
296
+ const endpoint = `/customers`;
297
+
298
+ return await apiRequest<CustomerResponse>(this, {
299
+ method: 'POST',
300
+ endpoint: endpoint,
301
+ body: body,
302
+ });
303
+ }
@@ -0,0 +1,44 @@
1
+ import { IExecuteFunctions, INodeProperties } from 'n8n-workflow';
2
+ import { apiRequest } from '../../../transport';
3
+ import { NodeResponse } from '../../../../nodeResponse';
4
+
5
+ export const description = {
6
+ name: 'Delete Customer',
7
+ value: 'delete',
8
+ description: 'Delete a single company by customer number',
9
+ action: 'Delete a customer',
10
+ };
11
+
12
+ export const properties: INodeProperties[] = [
13
+ {
14
+ displayName: 'Customer Number',
15
+ name: 'customerNumber',
16
+ type: 'string',
17
+ required: true,
18
+ default: '',
19
+ description: 'Unique identifier for customer',
20
+ displayOptions: {
21
+ show: {
22
+ resource: ['customer'],
23
+ operation: ['delete'],
24
+ },
25
+ },
26
+ },
27
+ ];
28
+
29
+ export async function execute(
30
+ this: IExecuteFunctions,
31
+ i: number
32
+ ): Promise<NodeResponse<null>> {
33
+ const customerNumber = this.getNodeParameter(
34
+ 'customerNumber',
35
+ i,
36
+ ''
37
+ ) as string;
38
+
39
+ const endpoint = `/customers/${encodeURIComponent(customerNumber)}`;
40
+ return await apiRequest<null>(this, {
41
+ method: 'DELETE',
42
+ endpoint,
43
+ });
44
+ }
@@ -0,0 +1,45 @@
1
+ import { IExecuteFunctions, INodeProperties } from 'n8n-workflow';
2
+ import { apiRequest } from '../../../transport';
3
+ import { CustomerResponse } from '../model';
4
+ import { NodeResponse } from '../../../../nodeResponse';
5
+
6
+ export const description = {
7
+ name: 'Get Customer',
8
+ value: 'get',
9
+ description: 'Get a single company by customer number',
10
+ action: 'Get a customer',
11
+ };
12
+
13
+ export const properties: INodeProperties[] = [
14
+ {
15
+ displayName: 'Customer Number',
16
+ name: 'customerNumber',
17
+ type: 'string',
18
+ required: true,
19
+ default: '',
20
+ description: 'Unique identifier for customer',
21
+ displayOptions: {
22
+ show: {
23
+ resource: ['customer'],
24
+ operation: ['get'],
25
+ },
26
+ },
27
+ },
28
+ ];
29
+
30
+ export async function execute(
31
+ this: IExecuteFunctions,
32
+ i: number
33
+ ): Promise<NodeResponse<CustomerResponse>> {
34
+ const customerNumber = this.getNodeParameter(
35
+ 'customerNumber',
36
+ i,
37
+ ''
38
+ ) as string;
39
+
40
+ const endpoint = `/customers/${encodeURIComponent(customerNumber)}`;
41
+ return await apiRequest<CustomerResponse>(this, {
42
+ method: 'GET',
43
+ endpoint,
44
+ });
45
+ }
@@ -0,0 +1,80 @@
1
+ import { IExecuteFunctions, INodeProperties, IDataObject } from 'n8n-workflow';
2
+ import { apiRequest } from '../../../transport';
3
+ import { filterParameters } from '../filterParameters';
4
+ import { sortParameters } from '../sortParameters';
5
+ import { CustomersResponse } from '../model';
6
+ import { NodeResponse } from '../../../../nodeResponse';
7
+
8
+ export const description = {
9
+ name: 'Get All Customers',
10
+ value: 'getAll',
11
+ description: 'Get all customers',
12
+ action: 'Get all customers',
13
+ };
14
+
15
+ export const properties: INodeProperties[] = [
16
+ {
17
+ displayName: 'Filter by',
18
+ name: 'filterParameters',
19
+ type: 'collection',
20
+ placeholder: 'Add Parameter',
21
+ default: {},
22
+ displayOptions: {
23
+ show: {
24
+ resource: ['customer'],
25
+ operation: ['getAll'],
26
+ },
27
+ },
28
+ options: filterParameters,
29
+ },
30
+ {
31
+ displayName: 'Sort by',
32
+ name: 'sortParameters',
33
+ type: 'collection',
34
+ placeholder: 'Add Parameter',
35
+ default: {},
36
+ displayOptions: {
37
+ show: {
38
+ resource: ['customer'],
39
+ operation: ['getAll'],
40
+ },
41
+ },
42
+ options: sortParameters,
43
+ },
44
+ ];
45
+
46
+ export async function execute(
47
+ this: IExecuteFunctions,
48
+ i: number
49
+ ): Promise<NodeResponse<CustomersResponse>> {
50
+ const filterParameters = this.getNodeParameter('filterParameters', i, {});
51
+ const sortParameters = this.getNodeParameter(
52
+ 'sortParameters',
53
+ i,
54
+ {}
55
+ ) as IDataObject;
56
+
57
+ const qs: IDataObject = {};
58
+ if (filterParameters) {
59
+ for (const [key, value] of Object.entries(filterParameters)) {
60
+ if (value !== '' && value !== undefined && value !== null) {
61
+ qs[key] = value;
62
+ }
63
+ }
64
+ }
65
+
66
+ if (sortParameters && Object.keys(sortParameters).length > 0) {
67
+ qs['sortby'] = Object.entries(sortParameters)
68
+ .filter(([, value]) => value)
69
+ .map(([, value]) => `${value}`)
70
+ .join('');
71
+ }
72
+
73
+ const endpoint = `/customers`;
74
+
75
+ return await apiRequest<CustomersResponse>(this, {
76
+ method: 'GET',
77
+ endpoint: endpoint,
78
+ qs,
79
+ });
80
+ }