@limetech/n8n-nodes-lime 2.3.1-dev.1 → 2.5.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.
- package/.github/workflows/lint.yml +1 -1
- package/.github/workflows/release.yml +16 -2
- package/.github/workflows/test-and-build.yml +0 -15
- package/CHANGELOG.md +35 -2
- package/nodes/errorHandling.ts +60 -0
- package/nodes/lime-crm/LimeCrmNode.node.ts +8 -0
- package/nodes/lime-crm/LimeCrmTrigger.node.ts +19 -5
- package/nodes/lime-crm/methods/getLimetypeProperties.ts +3 -1
- package/nodes/lime-crm/methods/getLimetypes.ts +2 -1
- package/nodes/lime-crm/methods/index.ts +5 -0
- package/nodes/lime-crm/methods/resourceMapping.ts +141 -0
- package/nodes/lime-crm/models/limetype.ts +18 -0
- package/nodes/lime-crm/resources/admin/index.ts +9 -4
- package/nodes/lime-crm/resources/admin/operations/getManyUsers.operation.ts +10 -2
- package/nodes/lime-crm/resources/admin/operations/getSingleUser.operation.ts +14 -15
- package/nodes/lime-crm/resources/data/index.ts +15 -6
- package/nodes/lime-crm/resources/data/operations/createSingleObject.operation.ts +25 -71
- package/nodes/lime-crm/resources/data/operations/deleteSingleObject.operation.ts +7 -2
- package/nodes/lime-crm/resources/data/operations/getManyObjects.operation.ts +6 -2
- package/nodes/lime-crm/resources/data/operations/getSingleFile.operation.ts +15 -3
- package/nodes/lime-crm/resources/data/operations/getSingleObject.operation.ts +15 -6
- package/nodes/lime-crm/resources/data/operations/updateSingleObject.operation.ts +41 -57
- package/nodes/lime-crm/resources/metadata/index.ts +7 -3
- package/nodes/lime-crm/resources/metadata/operations/getAllLimetypes.operation.ts +6 -2
- package/nodes/lime-crm/resources/metadata/operations/getSingleFileMetadata.operation.ts +18 -15
- package/nodes/lime-crm/resources/metadata/operations/getSingleLimetype.operation.ts +8 -3
- package/nodes/lime-crm/transport/commons.ts +34 -20
- package/nodes/lime-crm/transport/files.ts +72 -47
- package/nodes/lime-crm/transport/limeQuery.ts +2 -2
- package/nodes/lime-crm/transport/limeobjects.ts +22 -10
- package/nodes/lime-crm/transport/limetypes.ts +37 -16
- package/nodes/lime-crm/transport/users.ts +74 -38
- package/nodes/lime-crm/transport/webhooks.ts +5 -4
- package/nodes/lime-crm/utils/files.ts +27 -10
- package/nodes/lime-crm/utils/index.ts +1 -1
- package/nodes/response.ts +41 -3
- package/package.json +4 -2
- package/tests/nodes/lime-crm/methods.spec.ts +91 -0
- package/tests/nodes/lime-crm/utils.spec.ts +60 -25
- package/nodes/lime-crm/utils/propertyAdapters.ts +0 -75
- package/restore_script/README +0 -42
- package/restore_script/api_key_upload.txt +0 -0
- package/restore_script/cli.py +0 -73
- package/restore_script/download.py +0 -73
- package/restore_script/main.py +0 -19
- package/restore_script/poetry.lock +0 -162
- package/restore_script/pyproject.toml +0 -15
- package/restore_script/transfer.py +0 -41
- package/restore_script/upload.py +0 -66
- package/restore_script/utils.py +0 -42
- /package/{restore_script/api_key_download.txt → Dockerfile} +0 -0
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { callLimeApi, getLimeobject } from '.';
|
|
2
|
+
import { IExecuteFunctions, IBinaryData, BINARY_ENCODING } from 'n8n-workflow';
|
|
3
|
+
import { prepareResponseWithoutKeys } from './commons';
|
|
2
4
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from '
|
|
8
|
-
import { removeKeys } from './commons';
|
|
9
|
-
import { getFilenameFromHeader, setFilename } from '../utils';
|
|
10
|
-
|
|
5
|
+
getFilenameFromHeader,
|
|
6
|
+
handleWorkflowError,
|
|
7
|
+
setFilename,
|
|
8
|
+
} from '../utils';
|
|
9
|
+
import { APIResponse } from '../../response';
|
|
11
10
|
/**
|
|
12
11
|
* Endpoint path for Lime CRM file API.
|
|
13
12
|
*
|
|
@@ -71,13 +70,16 @@ export type FileMetadata = {
|
|
|
71
70
|
export async function getFileMetadata(
|
|
72
71
|
nodeContext: IExecuteFunctions,
|
|
73
72
|
id: string | number
|
|
74
|
-
): Promise<FileMetadata
|
|
73
|
+
): Promise<APIResponse<FileMetadata>> {
|
|
75
74
|
const url = `${LIME_FILE_URL}${id}/`;
|
|
76
|
-
const
|
|
75
|
+
const fileMetadataResponse = await callLimeApi<FileMetadata>(nodeContext, {
|
|
77
76
|
method: 'GET',
|
|
78
77
|
url: url,
|
|
79
78
|
});
|
|
80
|
-
|
|
79
|
+
|
|
80
|
+
if (!fileMetadataResponse.success) return fileMetadataResponse;
|
|
81
|
+
|
|
82
|
+
return prepareResponseWithoutKeys(fileMetadataResponse, ['_links']);
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
/**
|
|
@@ -97,19 +99,27 @@ export async function getFileMetadataByLimeobject(
|
|
|
97
99
|
limetype: string,
|
|
98
100
|
id: string,
|
|
99
101
|
fileTypeProperty: string
|
|
100
|
-
): Promise<FileMetadata
|
|
102
|
+
): Promise<APIResponse<FileMetadata>> {
|
|
101
103
|
const objectResponse = await getLimeobject(nodeContext, limetype, id);
|
|
102
|
-
|
|
104
|
+
if (!objectResponse.success) return objectResponse;
|
|
105
|
+
|
|
106
|
+
const fileId = objectResponse.data[fileTypeProperty] as string | undefined;
|
|
103
107
|
|
|
104
108
|
if (!fileId) {
|
|
105
|
-
|
|
106
|
-
nodeContext
|
|
107
|
-
|
|
109
|
+
return handleWorkflowError(
|
|
110
|
+
nodeContext,
|
|
111
|
+
{
|
|
112
|
+
message:
|
|
113
|
+
'The specified Limeobject does not have an associated file',
|
|
114
|
+
},
|
|
115
|
+
true
|
|
108
116
|
);
|
|
109
117
|
}
|
|
110
118
|
|
|
111
|
-
const
|
|
112
|
-
|
|
119
|
+
const fileMetadataResponse = await getFileMetadata(nodeContext, fileId);
|
|
120
|
+
if (!fileMetadataResponse.success) return fileMetadataResponse;
|
|
121
|
+
|
|
122
|
+
return prepareResponseWithoutKeys(fileMetadataResponse, ['_links']);
|
|
113
123
|
}
|
|
114
124
|
|
|
115
125
|
/**
|
|
@@ -125,7 +135,7 @@ export async function getFileMetadataByLimeobject(
|
|
|
125
135
|
export async function getFileContent(
|
|
126
136
|
nodeContext: IExecuteFunctions,
|
|
127
137
|
id: string | number
|
|
128
|
-
): Promise<IBinaryData
|
|
138
|
+
): Promise<APIResponse<IBinaryData>> {
|
|
129
139
|
const url = `${LIME_FILE_URL}${id}/contents/`;
|
|
130
140
|
|
|
131
141
|
const response = await callLimeApi<FileApiResponse>(nodeContext, {
|
|
@@ -139,13 +149,19 @@ export async function getFileContent(
|
|
|
139
149
|
json: false,
|
|
140
150
|
});
|
|
141
151
|
|
|
142
|
-
|
|
152
|
+
if (!response.success) return response;
|
|
153
|
+
|
|
154
|
+
const fileName =
|
|
155
|
+
getFilenameFromHeader(response.data.headers) || `file_${id}`;
|
|
143
156
|
const binaryData = await nodeContext.helpers.prepareBinaryData(
|
|
144
|
-
response.body
|
|
157
|
+
response.data.body
|
|
145
158
|
);
|
|
146
159
|
binaryData.fileName = setFilename(binaryData, fileName);
|
|
147
160
|
|
|
148
|
-
return
|
|
161
|
+
return {
|
|
162
|
+
success: true,
|
|
163
|
+
data: binaryData,
|
|
164
|
+
};
|
|
149
165
|
}
|
|
150
166
|
|
|
151
167
|
/**
|
|
@@ -165,14 +181,22 @@ export async function getFileContentByLimetype(
|
|
|
165
181
|
limetype: string,
|
|
166
182
|
id: string,
|
|
167
183
|
fileTypeProperty: string
|
|
168
|
-
): Promise<IBinaryData
|
|
184
|
+
): Promise<APIResponse<IBinaryData>> {
|
|
169
185
|
const limeObjectResponse = await getLimeobject(nodeContext, limetype, id);
|
|
170
|
-
|
|
186
|
+
if (!limeObjectResponse.success) return limeObjectResponse;
|
|
187
|
+
|
|
188
|
+
const fileId = limeObjectResponse.data[fileTypeProperty] as
|
|
189
|
+
| string
|
|
190
|
+
| undefined;
|
|
171
191
|
|
|
172
192
|
if (!fileId) {
|
|
173
|
-
|
|
174
|
-
nodeContext
|
|
175
|
-
|
|
193
|
+
return handleWorkflowError(
|
|
194
|
+
nodeContext,
|
|
195
|
+
{
|
|
196
|
+
message:
|
|
197
|
+
'The specified Limeobject does not have an associated file.',
|
|
198
|
+
},
|
|
199
|
+
true
|
|
176
200
|
);
|
|
177
201
|
}
|
|
178
202
|
|
|
@@ -194,27 +218,28 @@ export async function createFile(
|
|
|
194
218
|
nodeContext: IExecuteFunctions,
|
|
195
219
|
binary: IBinaryData,
|
|
196
220
|
fallbackFileName: string
|
|
197
|
-
): Promise<FileMetadata
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
221
|
+
): Promise<APIResponse<FileMetadata>> {
|
|
222
|
+
const response = await callLimeApi<FileMetadata>(nodeContext, {
|
|
223
|
+
method: 'POST',
|
|
224
|
+
url: LIME_FILE_URL,
|
|
225
|
+
requestOptions: {
|
|
226
|
+
body: Buffer.from(binary.data, BINARY_ENCODING),
|
|
227
|
+
headers: {
|
|
228
|
+
'Content-Disposition': `;filename*="UTF-8''${encodeURIComponent(binary.fileName || fallbackFileName)}"`,
|
|
229
|
+
'Content-Type': binary.mimeType,
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
if (!response.success)
|
|
234
|
+
return {
|
|
235
|
+
success: false,
|
|
236
|
+
data: {
|
|
237
|
+
error: {
|
|
238
|
+
message: response.data.error.message,
|
|
239
|
+
status: response.data.error.status,
|
|
208
240
|
},
|
|
209
241
|
},
|
|
210
|
-
}
|
|
211
|
-
} catch (error) {
|
|
212
|
-
// Remove metadata from the response to reduce its overall size
|
|
213
|
-
throw new NodeOperationError(
|
|
214
|
-
nodeContext.getNode(),
|
|
215
|
-
JSON.parse(error).error
|
|
216
|
-
);
|
|
217
|
-
}
|
|
242
|
+
};
|
|
218
243
|
|
|
219
|
-
return
|
|
244
|
+
return prepareResponseWithoutKeys(response, ['_links']);
|
|
220
245
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IAllExecuteFunctions } from 'n8n-workflow';
|
|
2
2
|
import { callLimeApi } from './commons';
|
|
3
3
|
import { APIResponsePrimitiveValue } from '../models';
|
|
4
|
-
|
|
4
|
+
import { APIResponse } from '../../response';
|
|
5
5
|
/**
|
|
6
6
|
* Endpoint path for Lime CRM Lime Query API.
|
|
7
7
|
*
|
|
@@ -47,7 +47,7 @@ export interface QueryResponse {
|
|
|
47
47
|
export async function queryLimeobjects(
|
|
48
48
|
nodeContext: IAllExecuteFunctions,
|
|
49
49
|
q: string
|
|
50
|
-
): Promise<QueryResponse
|
|
50
|
+
): Promise<APIResponse<QueryResponse>> {
|
|
51
51
|
const queryParameters = {
|
|
52
52
|
q: q,
|
|
53
53
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { callLimeApi,
|
|
1
|
+
import { callLimeApi, prepareResponseWithoutKeys } from './commons';
|
|
2
2
|
import { IAllExecuteFunctions } from 'n8n-workflow';
|
|
3
3
|
import { Limeobject } from '../models';
|
|
4
|
-
|
|
4
|
+
import { APIResponse } from '../../response';
|
|
5
5
|
/**
|
|
6
6
|
* Endpoint path for Lime CRM Limeobject API.
|
|
7
7
|
*
|
|
@@ -51,7 +51,7 @@ export async function createLimeobject(
|
|
|
51
51
|
nodeContext: IAllExecuteFunctions,
|
|
52
52
|
limetype: string,
|
|
53
53
|
data: object
|
|
54
|
-
): Promise<Limeobject
|
|
54
|
+
): Promise<APIResponse<Limeobject>> {
|
|
55
55
|
const url = `${LIMEOBJECT_URL}${limetype}/`;
|
|
56
56
|
const response = await callLimeApi<LimeobjectCrmApiResponse>(nodeContext, {
|
|
57
57
|
method: 'POST',
|
|
@@ -63,7 +63,11 @@ export async function createLimeobject(
|
|
|
63
63
|
limetype: limetype,
|
|
64
64
|
},
|
|
65
65
|
});
|
|
66
|
-
|
|
66
|
+
if (response.success) {
|
|
67
|
+
return prepareResponseWithoutKeys(response, ['_links']);
|
|
68
|
+
} else {
|
|
69
|
+
return response;
|
|
70
|
+
}
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
/**
|
|
@@ -81,9 +85,9 @@ export async function deleteLimeobject(
|
|
|
81
85
|
nodeContext: IAllExecuteFunctions,
|
|
82
86
|
limetype: string,
|
|
83
87
|
id: string
|
|
84
|
-
): Promise<
|
|
88
|
+
): Promise<APIResponse<Record<string, never>>> {
|
|
85
89
|
const url = `${LIMEOBJECT_URL}${limetype}/${id}/`;
|
|
86
|
-
return await callLimeApi(nodeContext, {
|
|
90
|
+
return await callLimeApi<Record<string, never>>(nodeContext, {
|
|
87
91
|
method: 'DELETE',
|
|
88
92
|
url: url,
|
|
89
93
|
errorMetadata: {
|
|
@@ -108,7 +112,7 @@ export async function getLimeobject(
|
|
|
108
112
|
nodeContext: IAllExecuteFunctions,
|
|
109
113
|
limetype: string,
|
|
110
114
|
id: string
|
|
111
|
-
): Promise<Limeobject
|
|
115
|
+
): Promise<APIResponse<Limeobject>> {
|
|
112
116
|
const url = `${LIMEOBJECT_URL}${limetype}/${id}/`;
|
|
113
117
|
const response = await callLimeApi<LimeobjectCrmApiResponse>(nodeContext, {
|
|
114
118
|
method: 'GET',
|
|
@@ -118,7 +122,11 @@ export async function getLimeobject(
|
|
|
118
122
|
id: id,
|
|
119
123
|
},
|
|
120
124
|
});
|
|
121
|
-
|
|
125
|
+
if (response.success) {
|
|
126
|
+
return prepareResponseWithoutKeys(response, ['_links']);
|
|
127
|
+
} else {
|
|
128
|
+
return response;
|
|
129
|
+
}
|
|
122
130
|
}
|
|
123
131
|
|
|
124
132
|
/**
|
|
@@ -138,7 +146,7 @@ export async function updateLimeobject(
|
|
|
138
146
|
limetype: string,
|
|
139
147
|
id: string,
|
|
140
148
|
data: object
|
|
141
|
-
): Promise<Limeobject
|
|
149
|
+
): Promise<APIResponse<Limeobject>> {
|
|
142
150
|
const url = `${LIMEOBJECT_URL}${limetype}/${id}/`;
|
|
143
151
|
const response = await callLimeApi<LimeobjectCrmApiResponse>(nodeContext, {
|
|
144
152
|
method: 'PUT',
|
|
@@ -151,5 +159,9 @@ export async function updateLimeobject(
|
|
|
151
159
|
id: id,
|
|
152
160
|
},
|
|
153
161
|
});
|
|
154
|
-
|
|
162
|
+
if (response.success) {
|
|
163
|
+
return prepareResponseWithoutKeys(response, ['_links']);
|
|
164
|
+
} else {
|
|
165
|
+
return response;
|
|
166
|
+
}
|
|
155
167
|
}
|
|
@@ -2,6 +2,7 @@ import { callLimeApi } from '.';
|
|
|
2
2
|
import { IAllExecuteFunctions } from 'n8n-workflow';
|
|
3
3
|
import { removeKeys } from './commons';
|
|
4
4
|
import { Limetype, LimetypeProperty } from '../models';
|
|
5
|
+
import { APIResponse } from '../../response';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Endpoint path for Lime CRM Limetype API.
|
|
@@ -113,7 +114,7 @@ function deserializeLimetype(limetype: LimetypeCrmApiResponse): Limetype {
|
|
|
113
114
|
*/
|
|
114
115
|
export async function getLimetypesFromApi(
|
|
115
116
|
nodeContext: IAllExecuteFunctions
|
|
116
|
-
): Promise<Limetype[]
|
|
117
|
+
): Promise<APIResponse<Limetype[]>> {
|
|
117
118
|
const response = await callLimeApi<LimetypesCrmApiResponse>(nodeContext, {
|
|
118
119
|
method: 'GET',
|
|
119
120
|
url: LIMETYPE_URL,
|
|
@@ -123,7 +124,16 @@ export async function getLimetypesFromApi(
|
|
|
123
124
|
},
|
|
124
125
|
},
|
|
125
126
|
});
|
|
126
|
-
|
|
127
|
+
if (response.success) {
|
|
128
|
+
return {
|
|
129
|
+
success: true,
|
|
130
|
+
data:
|
|
131
|
+
response.data._embedded?.limetypes.map(deserializeLimetype) ||
|
|
132
|
+
[],
|
|
133
|
+
};
|
|
134
|
+
} else {
|
|
135
|
+
return response;
|
|
136
|
+
}
|
|
127
137
|
}
|
|
128
138
|
|
|
129
139
|
/**
|
|
@@ -139,7 +149,7 @@ export async function getLimetypesFromApi(
|
|
|
139
149
|
export async function getLimetype(
|
|
140
150
|
nodeContext: IAllExecuteFunctions,
|
|
141
151
|
limetype: string
|
|
142
|
-
): Promise<Limetype
|
|
152
|
+
): Promise<APIResponse<Limetype>> {
|
|
143
153
|
const url = `${LIMETYPE_URL}${limetype}/`;
|
|
144
154
|
const response = await callLimeApi<LimetypeCrmApiResponse>(nodeContext, {
|
|
145
155
|
method: 'GET',
|
|
@@ -150,8 +160,14 @@ export async function getLimetype(
|
|
|
150
160
|
},
|
|
151
161
|
},
|
|
152
162
|
});
|
|
153
|
-
|
|
154
|
-
|
|
163
|
+
if (response.success) {
|
|
164
|
+
return {
|
|
165
|
+
success: true,
|
|
166
|
+
data: deserializeLimetype(response.data),
|
|
167
|
+
};
|
|
168
|
+
} else {
|
|
169
|
+
return response;
|
|
170
|
+
}
|
|
155
171
|
}
|
|
156
172
|
|
|
157
173
|
/**
|
|
@@ -167,7 +183,7 @@ export async function getLimetype(
|
|
|
167
183
|
export async function getProperties(
|
|
168
184
|
nodeContext: IAllExecuteFunctions,
|
|
169
185
|
limetype: string
|
|
170
|
-
): Promise<LimetypeProperty[]
|
|
186
|
+
): Promise<APIResponse<LimetypeProperty[]>> {
|
|
171
187
|
const url = `${LIMETYPE_URL}${limetype}/`;
|
|
172
188
|
const response = await callLimeApi<LimetypePropertiesApiResponse>(
|
|
173
189
|
nodeContext,
|
|
@@ -184,14 +200,19 @@ export async function getProperties(
|
|
|
184
200
|
},
|
|
185
201
|
}
|
|
186
202
|
);
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
203
|
+
if (response.success) {
|
|
204
|
+
return {
|
|
205
|
+
success: true,
|
|
206
|
+
data:
|
|
207
|
+
response.data._embedded.properties.map(
|
|
208
|
+
(property) =>
|
|
209
|
+
removeKeys(property, [
|
|
210
|
+
'_links',
|
|
211
|
+
'_embedded',
|
|
212
|
+
]) as LimetypeProperty
|
|
213
|
+
) || [],
|
|
214
|
+
};
|
|
215
|
+
} else {
|
|
216
|
+
return response;
|
|
217
|
+
}
|
|
197
218
|
}
|
|
@@ -2,7 +2,7 @@ import { callLimeApi } from './commons';
|
|
|
2
2
|
import {
|
|
3
3
|
IAllExecuteFunctions,
|
|
4
4
|
LoggerProxy as Logger,
|
|
5
|
-
|
|
5
|
+
NodeApiError,
|
|
6
6
|
} from 'n8n-workflow';
|
|
7
7
|
import {
|
|
8
8
|
User,
|
|
@@ -14,7 +14,8 @@ import {
|
|
|
14
14
|
import { getLimetypesFromApi } from './limetypes';
|
|
15
15
|
import { queryLimeobjects, QueryResponse } from './limeQuery';
|
|
16
16
|
import { getLimeobject } from './limeobjects';
|
|
17
|
-
|
|
17
|
+
import { APIResponse } from '../../response';
|
|
18
|
+
import { handleWorkflowError } from '../../errorHandling';
|
|
18
19
|
const USERS_URL = 'api/v1/admin/users/';
|
|
19
20
|
|
|
20
21
|
type UserQueryParameters = {
|
|
@@ -49,21 +50,30 @@ function findCoworkerLimetype(limetypes: Limetype[]): Limetype | undefined {
|
|
|
49
50
|
*
|
|
50
51
|
* @param nodeContext - The n8n execution context
|
|
51
52
|
* @returns The coworker limetype object
|
|
52
|
-
* @throws
|
|
53
|
+
* @throws NodeApiError if no coworker limetype is found
|
|
53
54
|
* @internal
|
|
54
55
|
*/
|
|
55
56
|
async function findCoworker(
|
|
56
57
|
nodeContext: IAllExecuteFunctions
|
|
57
|
-
): Promise<Limetype
|
|
58
|
+
): Promise<APIResponse<Limetype>> {
|
|
58
59
|
const response = await getLimetypesFromApi(nodeContext);
|
|
59
|
-
|
|
60
|
+
if (!response.success) {
|
|
61
|
+
return response;
|
|
62
|
+
}
|
|
63
|
+
const coworker = findCoworkerLimetype(response.data);
|
|
60
64
|
if (!coworker) {
|
|
61
|
-
|
|
62
|
-
nodeContext
|
|
63
|
-
|
|
65
|
+
return handleWorkflowError(
|
|
66
|
+
nodeContext,
|
|
67
|
+
{
|
|
68
|
+
message: `No limetype with 'user' property found to get coworker`,
|
|
69
|
+
},
|
|
70
|
+
true
|
|
64
71
|
);
|
|
65
72
|
}
|
|
66
|
-
return
|
|
73
|
+
return {
|
|
74
|
+
success: true,
|
|
75
|
+
data: coworker,
|
|
76
|
+
};
|
|
67
77
|
}
|
|
68
78
|
|
|
69
79
|
/**
|
|
@@ -73,14 +83,14 @@ async function findCoworker(
|
|
|
73
83
|
* @param coworker - The limetype definition for the coworker
|
|
74
84
|
* @param userId - The ID of the user whose coworker data is to be fetched
|
|
75
85
|
* @returns The coworker data response from the Lime Query API
|
|
76
|
-
* @throws
|
|
86
|
+
* @throws NodeApiError' property is found in the coworker limetype
|
|
77
87
|
* @internal
|
|
78
88
|
*/
|
|
79
89
|
async function getCoworker(
|
|
80
90
|
nodeContext: IAllExecuteFunctions,
|
|
81
91
|
coworker: Limetype,
|
|
82
92
|
userId: string | number
|
|
83
|
-
): Promise<QueryResponse
|
|
93
|
+
): Promise<APIResponse<QueryResponse>> {
|
|
84
94
|
// 'hasmany' properties are not supported in the response format of Lime Query API
|
|
85
95
|
const properties = Object.fromEntries(
|
|
86
96
|
coworker.properties
|
|
@@ -92,10 +102,9 @@ async function getCoworker(
|
|
|
92
102
|
(prop) => prop.type === 'user'
|
|
93
103
|
);
|
|
94
104
|
if (!userProperty) {
|
|
95
|
-
throw new
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
);
|
|
105
|
+
throw new NodeApiError(nodeContext.getNode(), {
|
|
106
|
+
message: `No property of type 'user' found in ${coworker.name} limetype`,
|
|
107
|
+
});
|
|
99
108
|
}
|
|
100
109
|
|
|
101
110
|
const responseFormat = {
|
|
@@ -135,7 +144,7 @@ export async function fetchManyUsers(
|
|
|
135
144
|
userType: UserType | NullOptionType = '',
|
|
136
145
|
limit: number = DEFAULT_API_OBJECT_LIMIT,
|
|
137
146
|
withCoworker: boolean = false
|
|
138
|
-
): Promise<User[]
|
|
147
|
+
): Promise<APIResponse<User[]>> {
|
|
139
148
|
const queryParams: UserQueryParameters = {
|
|
140
149
|
_limit: limit,
|
|
141
150
|
};
|
|
@@ -154,23 +163,31 @@ export async function fetchManyUsers(
|
|
|
154
163
|
},
|
|
155
164
|
});
|
|
156
165
|
|
|
157
|
-
if (!withCoworker) return response;
|
|
158
|
-
|
|
166
|
+
if (!response.success || !withCoworker) return response;
|
|
167
|
+
|
|
168
|
+
const coworkerLimetypeResponse = await findCoworker(nodeContext);
|
|
169
|
+
if (!coworkerLimetypeResponse.success) return coworkerLimetypeResponse;
|
|
170
|
+
|
|
171
|
+
const coworkerLimetype = coworkerLimetypeResponse.data;
|
|
159
172
|
|
|
160
173
|
const usersWithCoworkers: User[] = [];
|
|
161
|
-
for (const user of response) {
|
|
174
|
+
for (const user of response.data) {
|
|
162
175
|
const coworkerResponse = await getCoworker(
|
|
163
176
|
nodeContext,
|
|
164
|
-
|
|
177
|
+
coworkerLimetype,
|
|
165
178
|
user.id
|
|
166
179
|
);
|
|
180
|
+
if (!coworkerResponse.success) return coworkerResponse;
|
|
167
181
|
usersWithCoworkers.push({
|
|
168
182
|
...user,
|
|
169
|
-
[
|
|
183
|
+
[coworkerLimetype.name]: coworkerResponse.data.objects[0] || null,
|
|
170
184
|
});
|
|
171
185
|
}
|
|
172
186
|
|
|
173
|
-
return
|
|
187
|
+
return {
|
|
188
|
+
success: true,
|
|
189
|
+
data: usersWithCoworkers,
|
|
190
|
+
};
|
|
174
191
|
}
|
|
175
192
|
|
|
176
193
|
/**
|
|
@@ -189,7 +206,7 @@ export async function fetchSingleUserById(
|
|
|
189
206
|
nodeContext: IAllExecuteFunctions,
|
|
190
207
|
id: string,
|
|
191
208
|
withCoworker: boolean = false
|
|
192
|
-
): Promise<User
|
|
209
|
+
): Promise<APIResponse<User>> {
|
|
193
210
|
const url = `${USERS_URL}${id}`;
|
|
194
211
|
const userResponse = await callLimeApi<User>(nodeContext, {
|
|
195
212
|
method: 'GET',
|
|
@@ -199,13 +216,21 @@ export async function fetchSingleUserById(
|
|
|
199
216
|
},
|
|
200
217
|
});
|
|
201
218
|
|
|
202
|
-
if (!withCoworker) return userResponse;
|
|
203
|
-
const
|
|
204
|
-
|
|
219
|
+
if (!userResponse.success || !withCoworker) return userResponse;
|
|
220
|
+
const coworkerLimetypeResponse = await findCoworker(nodeContext);
|
|
221
|
+
if (!coworkerLimetypeResponse.success) return coworkerLimetypeResponse;
|
|
222
|
+
|
|
223
|
+
const coworkerResponse = await getCoworker(
|
|
224
|
+
nodeContext,
|
|
225
|
+
coworkerLimetypeResponse.data,
|
|
226
|
+
id
|
|
227
|
+
);
|
|
228
|
+
if (!coworkerResponse.success) return coworkerResponse;
|
|
205
229
|
|
|
206
230
|
return {
|
|
207
231
|
...userResponse,
|
|
208
|
-
[
|
|
232
|
+
[coworkerLimetypeResponse.data.name]:
|
|
233
|
+
coworkerResponse.data.objects[0] || null,
|
|
209
234
|
};
|
|
210
235
|
}
|
|
211
236
|
|
|
@@ -228,25 +253,33 @@ export async function fetchSingleUserByLimeobjectId(
|
|
|
228
253
|
nodeContext: IAllExecuteFunctions,
|
|
229
254
|
id: string,
|
|
230
255
|
withCoworker: boolean = false
|
|
231
|
-
): Promise<User
|
|
232
|
-
const
|
|
256
|
+
): Promise<APIResponse<User>> {
|
|
257
|
+
const coworkerLimetypeResponse = await findCoworker(nodeContext);
|
|
258
|
+
if (!coworkerLimetypeResponse.success) return coworkerLimetypeResponse;
|
|
259
|
+
|
|
260
|
+
const coworkerLimetype = coworkerLimetypeResponse.data;
|
|
261
|
+
|
|
233
262
|
const coworkerResponse = await getLimeobject(
|
|
234
263
|
nodeContext,
|
|
235
|
-
|
|
264
|
+
coworkerLimetype.name,
|
|
236
265
|
id
|
|
237
266
|
);
|
|
267
|
+
if (!coworkerResponse.success) return coworkerResponse;
|
|
238
268
|
|
|
239
|
-
const userProperty =
|
|
269
|
+
const userProperty = coworkerLimetype.properties.find(
|
|
240
270
|
(prop) => prop.type === 'user'
|
|
241
271
|
);
|
|
242
272
|
if (!userProperty) {
|
|
243
|
-
|
|
244
|
-
nodeContext
|
|
245
|
-
|
|
273
|
+
return handleWorkflowError(
|
|
274
|
+
nodeContext,
|
|
275
|
+
{
|
|
276
|
+
message: `No property of type 'user' found in ${coworkerLimetype.name} limetype`,
|
|
277
|
+
},
|
|
278
|
+
true
|
|
246
279
|
);
|
|
247
280
|
}
|
|
248
281
|
|
|
249
|
-
const url = `${USERS_URL}${coworkerResponse[userProperty.name]}`;
|
|
282
|
+
const url = `${USERS_URL}${coworkerResponse.data[userProperty.name]}`;
|
|
250
283
|
const userResponse = await callLimeApi<User>(nodeContext, {
|
|
251
284
|
method: 'GET',
|
|
252
285
|
url: url,
|
|
@@ -255,10 +288,13 @@ export async function fetchSingleUserByLimeobjectId(
|
|
|
255
288
|
},
|
|
256
289
|
});
|
|
257
290
|
|
|
258
|
-
if (!withCoworker) return userResponse;
|
|
291
|
+
if (!userResponse.success || !withCoworker) return userResponse;
|
|
259
292
|
|
|
260
293
|
return {
|
|
261
|
-
|
|
262
|
-
|
|
294
|
+
success: true,
|
|
295
|
+
data: {
|
|
296
|
+
...userResponse.data,
|
|
297
|
+
[coworkerLimetype.name]: coworkerResponse.data || null,
|
|
298
|
+
},
|
|
263
299
|
};
|
|
264
300
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { callLimeApi } from '.';
|
|
2
2
|
import { IAllExecuteFunctions } from 'n8n-workflow';
|
|
3
3
|
import { CreateWebhook, Webhook } from '../models';
|
|
4
|
+
import { APIResponse } from '../../response';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Endpoint path for Lime CRM Subscription API.
|
|
@@ -44,7 +45,7 @@ export interface ApiResponseWebhook {
|
|
|
44
45
|
export async function getSubscription(
|
|
45
46
|
nodeContext: IAllExecuteFunctions,
|
|
46
47
|
webhook: Webhook
|
|
47
|
-
): Promise<ApiResponseWebhook
|
|
48
|
+
): Promise<APIResponse<ApiResponseWebhook>> {
|
|
48
49
|
return await callLimeApi(nodeContext, {
|
|
49
50
|
method: 'GET',
|
|
50
51
|
url: `${SUBSCRIPTION_URL}${webhook.data.webhookId}`,
|
|
@@ -65,7 +66,7 @@ export async function getSubscription(
|
|
|
65
66
|
export async function listSubscriptionsWithExistingData(
|
|
66
67
|
nodeContext: IAllExecuteFunctions,
|
|
67
68
|
webhook: Webhook
|
|
68
|
-
): Promise<ApiResponseWebhook[]
|
|
69
|
+
): Promise<APIResponse<ApiResponseWebhook[]>> {
|
|
69
70
|
return await callLimeApi(nodeContext, {
|
|
70
71
|
method: 'GET',
|
|
71
72
|
url: SUBSCRIPTION_URL,
|
|
@@ -93,7 +94,7 @@ export async function listSubscriptionsWithExistingData(
|
|
|
93
94
|
export async function createSubscription(
|
|
94
95
|
nodeContext: IAllExecuteFunctions,
|
|
95
96
|
webhook: CreateWebhook
|
|
96
|
-
): Promise<ApiResponseWebhook
|
|
97
|
+
): Promise<APIResponse<ApiResponseWebhook>> {
|
|
97
98
|
return await callLimeApi(nodeContext, {
|
|
98
99
|
method: 'POST',
|
|
99
100
|
url: SUBSCRIPTION_URL,
|
|
@@ -122,7 +123,7 @@ export async function createSubscription(
|
|
|
122
123
|
export async function deleteSubscription(
|
|
123
124
|
nodeContext: IAllExecuteFunctions,
|
|
124
125
|
webhook: Webhook
|
|
125
|
-
): Promise<void
|
|
126
|
+
): Promise<APIResponse<void>> {
|
|
126
127
|
return await callLimeApi(nodeContext, {
|
|
127
128
|
method: 'DELETE',
|
|
128
129
|
url: `${SUBSCRIPTION_URL}${webhook.data.webhookId}/`,
|