@limetech/n8n-nodes-lime 0.4.0 → 0.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/.prettierignore +3 -1
- package/CHANGELOG.md +93 -0
- package/README.md +1 -8
- package/credentials/LimeCrmApi.credentials.ts +6 -6
- package/docker-compose.yml +9 -3
- package/nodes/fortnox/Fortnox.node.ts +3 -3
- package/nodes/fortnox/FortnoxTrigger.node.ts +2 -2
- package/nodes/lime-crm/LimeCrmNode.node.ts +54 -67
- package/nodes/lime-crm/LimeCrmTrigger.node.ts +17 -24
- package/nodes/lime-crm/commons/constants.ts +2 -3
- package/nodes/lime-crm/commons/files.ts +162 -0
- package/nodes/lime-crm/commons/index.ts +4 -4
- package/nodes/lime-crm/commons/webhook.ts +15 -3
- package/nodes/lime-crm/methods/getLimetypeProperties.ts +67 -0
- package/nodes/lime-crm/methods/getLimetypes.ts +21 -0
- package/nodes/lime-crm/methods/index.ts +6 -2
- package/nodes/lime-crm/model.ts +22 -0
- package/nodes/lime-crm/resources/data/index.ts +80 -0
- package/nodes/lime-crm/resources/{limeObject/operations/create.operation.ts → data/operations/createSingleObject.ts} +53 -30
- package/nodes/lime-crm/resources/{limeObject/operations/delete.operation.ts → data/operations/deleteSingleObject.ts} +15 -15
- package/nodes/lime-crm/resources/data/operations/getManyObjects.ts +356 -0
- package/nodes/lime-crm/resources/data/operations/getSingleFile.ts +138 -0
- package/nodes/lime-crm/resources/data/operations/getSingleObject.ts +83 -0
- package/nodes/lime-crm/resources/{limeObject/operations/update.operation.ts → data/operations/updateSingleObject.operation.ts} +51 -23
- package/nodes/lime-crm/resources/erpConnector/index.ts +3 -3
- package/nodes/lime-crm/resources/erpConnector/operations/transform.operation.ts +14 -14
- package/nodes/lime-crm/resources/erpConnector/transform.ts +3 -3
- package/nodes/lime-crm/resources/erpConnector/transformers/baseTransformer.ts +2 -2
- package/nodes/lime-crm/resources/erpConnector/transformers/fortnox.ts +8 -8
- package/nodes/lime-crm/resources/metadata/index.ts +57 -0
- package/nodes/lime-crm/resources/metadata/operations/getAllLimetypes.operation.ts +18 -0
- package/nodes/lime-crm/resources/metadata/operations/getSingleFileMetadata.ts +130 -0
- package/nodes/lime-crm/resources/metadata/operations/getSingleLimetype.ts +36 -0
- package/nodes/lime-crm/transport/commons.ts +14 -2
- package/nodes/lime-crm/transport/files.ts +155 -0
- package/nodes/lime-crm/transport/index.ts +14 -7
- package/nodes/lime-crm/transport/limeQuery.ts +2 -4
- package/nodes/lime-crm/transport/limeobjects.ts +79 -44
- package/nodes/lime-crm/transport/limetypes.ts +80 -24
- package/package.json +4 -3
- package/restore_script/README +42 -0
- package/restore_script/api_key_download.txt +0 -0
- package/restore_script/api_key_upload.txt +0 -0
- package/restore_script/cli.py +73 -0
- package/restore_script/download.py +73 -0
- package/restore_script/main.py +19 -0
- package/restore_script/poetry.lock +162 -0
- package/restore_script/pyproject.toml +15 -0
- package/restore_script/transfer.py +41 -0
- package/restore_script/upload.py +66 -0
- package/restore_script/utils.py +42 -0
- package/tests/transform.spec.ts +6 -6
- package/nodes/lime-crm/commons/limetype.ts +0 -11
- package/nodes/lime-crm/methods/getLimeTypeProperties.ts +0 -27
- package/nodes/lime-crm/methods/getLimeTypes.ts +0 -23
- package/nodes/lime-crm/resources/limeObject/index.ts +0 -64
- package/nodes/lime-crm/resources/limeObject/operations/fetchMany.operation.ts +0 -112
- package/nodes/lime-crm/resources/limeObject/operations/get.operation.ts +0 -54
- package/nodes/lime-crm/resources/limeQuery/index.ts +0 -40
- package/nodes/lime-crm/resources/limeQuery/operations/query.operation.ts +0 -222
- package/nodes/lime-crm/resources/limeType/index.ts +0 -58
- package/nodes/lime-crm/resources/limeType/operations/getProperties.operation.ts +0 -42
- package/nodes/lime-crm/resources/limeType/operations/getType.operation.ts +0 -36
- package/nodes/lime-crm/resources/limeType/operations/listTypes.operation.ts +0 -18
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { callLimeApi, getLimeobject } from '.';
|
|
2
|
+
import { IExecuteFunctions, IBinaryData, BINARY_ENCODING } from 'n8n-workflow';
|
|
3
|
+
import { NodeResponse } from '../../nodeResponse';
|
|
4
|
+
import { removeKeys } from './commons';
|
|
5
|
+
import { getFilenameFromHeader, setFilename } from '../commons';
|
|
6
|
+
|
|
7
|
+
const LIME_FILE_URL = '/api/v1/file/';
|
|
8
|
+
|
|
9
|
+
interface FileApiResponse {
|
|
10
|
+
headers: Record<string, string | string[] | undefined>;
|
|
11
|
+
body: Buffer;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface FileMetadata {
|
|
15
|
+
filename: string;
|
|
16
|
+
id: number;
|
|
17
|
+
size: number;
|
|
18
|
+
content_type: string;
|
|
19
|
+
extension: string;
|
|
20
|
+
created_by: number;
|
|
21
|
+
locked_by: number;
|
|
22
|
+
last_modified: string;
|
|
23
|
+
_links?: { [key: string]: { href: string } };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function getFileMetadata(
|
|
27
|
+
nodeContext: IExecuteFunctions,
|
|
28
|
+
id: string | number
|
|
29
|
+
): Promise<NodeResponse<FileMetadata>> {
|
|
30
|
+
const url = `${LIME_FILE_URL}${id}/`;
|
|
31
|
+
const response = await callLimeApi<FileMetadata>(nodeContext, 'GET', url);
|
|
32
|
+
if (!response.success) {
|
|
33
|
+
return response;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
success: true,
|
|
38
|
+
data: removeKeys(response.data, ['_links']),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function getFileMetadataByLimeobject(
|
|
43
|
+
nodeContext: IExecuteFunctions,
|
|
44
|
+
limetype: string,
|
|
45
|
+
id: string,
|
|
46
|
+
fileTypeProperty: string
|
|
47
|
+
): Promise<NodeResponse<FileMetadata>> {
|
|
48
|
+
const objectResponse = await getLimeobject(nodeContext, limetype, id);
|
|
49
|
+
if (!objectResponse.success) {
|
|
50
|
+
return objectResponse;
|
|
51
|
+
}
|
|
52
|
+
const fileId = objectResponse.data[fileTypeProperty] as string | undefined;
|
|
53
|
+
|
|
54
|
+
if (!fileId) {
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
error: 'The specified Limeobject does not have an associated file.',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const metadataResponse = await getFileMetadata(nodeContext, fileId);
|
|
62
|
+
if (!metadataResponse.success) {
|
|
63
|
+
return metadataResponse;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
success: true,
|
|
68
|
+
data: removeKeys(metadataResponse.data, ['_links']),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function getFileContent(
|
|
73
|
+
nodeContext: IExecuteFunctions,
|
|
74
|
+
id: string | number
|
|
75
|
+
): Promise<NodeResponse<IBinaryData>> {
|
|
76
|
+
const url = `${LIME_FILE_URL}${id}/contents/`;
|
|
77
|
+
|
|
78
|
+
const response = await callLimeApi<FileApiResponse>(
|
|
79
|
+
nodeContext,
|
|
80
|
+
'GET',
|
|
81
|
+
url,
|
|
82
|
+
{
|
|
83
|
+
encoding: null,
|
|
84
|
+
responseType: 'stream',
|
|
85
|
+
resolveWithFullResponse: true,
|
|
86
|
+
},
|
|
87
|
+
false
|
|
88
|
+
);
|
|
89
|
+
if (!response.success) {
|
|
90
|
+
return response;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const fileName =
|
|
94
|
+
getFilenameFromHeader(response.data.headers) || `file_${id}`;
|
|
95
|
+
const binaryData = await nodeContext.helpers.prepareBinaryData(
|
|
96
|
+
response.data.body
|
|
97
|
+
);
|
|
98
|
+
binaryData.fileName = setFilename(binaryData, fileName);
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
success: true,
|
|
102
|
+
data: binaryData,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function getFileContentByLimetype(
|
|
107
|
+
nodeContext: IExecuteFunctions,
|
|
108
|
+
limetype: string,
|
|
109
|
+
id: string,
|
|
110
|
+
fileTypeProperty: string
|
|
111
|
+
): Promise<NodeResponse<IBinaryData>> {
|
|
112
|
+
const objectResponse = await getLimeobject(nodeContext, limetype, id);
|
|
113
|
+
if (!objectResponse.success) {
|
|
114
|
+
return objectResponse;
|
|
115
|
+
}
|
|
116
|
+
const fileId = objectResponse.data[fileTypeProperty] as string | undefined;
|
|
117
|
+
|
|
118
|
+
if (!fileId) {
|
|
119
|
+
return {
|
|
120
|
+
success: false,
|
|
121
|
+
error: 'The specified Limeobject does not have an associated file.',
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return await getFileContent(nodeContext, fileId);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export async function createFile(
|
|
129
|
+
nodeContext: IExecuteFunctions,
|
|
130
|
+
binary: IBinaryData,
|
|
131
|
+
fallbackFileName: string
|
|
132
|
+
): Promise<NodeResponse<FileMetadata>> {
|
|
133
|
+
const response = await callLimeApi<FileMetadata>(
|
|
134
|
+
nodeContext,
|
|
135
|
+
'POST',
|
|
136
|
+
LIME_FILE_URL,
|
|
137
|
+
{
|
|
138
|
+
body: Buffer.from(binary.data, BINARY_ENCODING),
|
|
139
|
+
headers: {
|
|
140
|
+
'Content-Disposition': `;filename*="UTF-8''${encodeURIComponent(binary.fileName || fallbackFileName)}"`,
|
|
141
|
+
'Content-Type': binary.mimeType,
|
|
142
|
+
},
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
// Remove metadata from the response to reduce its overall size
|
|
147
|
+
if (!response.success) {
|
|
148
|
+
return { success: false, error: response.error };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
success: true,
|
|
153
|
+
data: removeKeys(response.data, ['_links']),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
@@ -4,15 +4,22 @@ export {
|
|
|
4
4
|
createSubscription,
|
|
5
5
|
listSubscriptionsWithExistingData,
|
|
6
6
|
} from './webhooks';
|
|
7
|
-
export {
|
|
7
|
+
export { getLimetypesFromApi, getProperties } from './limetypes';
|
|
8
8
|
|
|
9
9
|
export {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
createLimeobject,
|
|
11
|
+
deleteLimeobject,
|
|
12
|
+
updateLimeobject,
|
|
13
|
+
getLimeobject,
|
|
14
|
+
fetchManyLimeobjects,
|
|
15
15
|
} from './limeobjects';
|
|
16
16
|
export { startCreateOrUpdateObjectsTask } from './erpConnector';
|
|
17
|
-
export {
|
|
17
|
+
export { queryLimeobjects } from './limeQuery';
|
|
18
|
+
export {
|
|
19
|
+
createFile,
|
|
20
|
+
getFileContent,
|
|
21
|
+
getFileContentByLimetype,
|
|
22
|
+
getFileMetadata,
|
|
23
|
+
getFileMetadataByLimeobject,
|
|
24
|
+
} from './files';
|
|
18
25
|
export { callLimeApi } from './commons';
|
|
@@ -12,14 +12,12 @@ export interface QueryResponse {
|
|
|
12
12
|
objects: IncludedProperties[];
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export async function
|
|
15
|
+
export async function queryLimeobjects(
|
|
16
16
|
nodeContext: IAllExecuteFunctions,
|
|
17
|
-
q: string
|
|
18
|
-
activeObject: string
|
|
17
|
+
q: string
|
|
19
18
|
): Promise<NodeResponse<QueryResponse>> {
|
|
20
19
|
const queryParameters = {
|
|
21
20
|
q: q,
|
|
22
|
-
activeObject: activeObject,
|
|
23
21
|
};
|
|
24
22
|
|
|
25
23
|
return await callLimeApi(nodeContext, 'GET', LIME_QUERY_URL, {
|
|
@@ -1,41 +1,56 @@
|
|
|
1
|
-
import { callLimeApi } from './commons';
|
|
1
|
+
import { callLimeApi, removeKeys } from './commons';
|
|
2
2
|
import { IAllExecuteFunctions, IDataObject } from 'n8n-workflow';
|
|
3
3
|
import { NodeResponse } from '../../nodeResponse';
|
|
4
|
+
import { Limeobject } from '../model';
|
|
4
5
|
|
|
5
6
|
const LIMEOBJECT_URL = '/api/v1/limeobject/';
|
|
6
7
|
|
|
7
|
-
interface
|
|
8
|
+
interface LimeobjectCrmApiResponse {
|
|
9
|
+
id_: number;
|
|
10
|
+
_links: object;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface FetchManyLimeobjectsApiResponse {
|
|
8
14
|
_embedded: {
|
|
9
|
-
limeobjects:
|
|
15
|
+
limeobjects: LimeobjectCrmApiResponse[];
|
|
10
16
|
};
|
|
11
17
|
}
|
|
12
18
|
|
|
13
|
-
export async function
|
|
19
|
+
export async function createLimeobject(
|
|
14
20
|
nodeContext: IAllExecuteFunctions,
|
|
15
|
-
|
|
21
|
+
limetype: string,
|
|
16
22
|
data: object
|
|
17
|
-
): Promise<NodeResponse<
|
|
18
|
-
const url = `${LIMEOBJECT_URL}${
|
|
19
|
-
const response = await callLimeApi(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
): Promise<NodeResponse<Limeobject>> {
|
|
24
|
+
const url = `${LIMEOBJECT_URL}${limetype}/`;
|
|
25
|
+
const response = await callLimeApi<LimeobjectCrmApiResponse>(
|
|
26
|
+
nodeContext,
|
|
27
|
+
'POST',
|
|
28
|
+
url,
|
|
29
|
+
{
|
|
30
|
+
body: data,
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
if (response.success)
|
|
34
|
+
return {
|
|
35
|
+
success: true,
|
|
36
|
+
data: removeKeys(response.data, ['_links']),
|
|
37
|
+
};
|
|
23
38
|
|
|
24
39
|
return {
|
|
25
40
|
...response,
|
|
26
41
|
metadata: {
|
|
27
42
|
...response.metadata,
|
|
28
|
-
|
|
43
|
+
limetype: limetype,
|
|
29
44
|
},
|
|
30
45
|
};
|
|
31
46
|
}
|
|
32
47
|
|
|
33
|
-
export async function
|
|
48
|
+
export async function deleteLimeobject(
|
|
34
49
|
nodeContext: IAllExecuteFunctions,
|
|
35
|
-
|
|
50
|
+
limetype: string,
|
|
36
51
|
id: string
|
|
37
52
|
): Promise<NodeResponse<void>> {
|
|
38
|
-
const url = `${LIMEOBJECT_URL}${
|
|
53
|
+
const url = `${LIMEOBJECT_URL}${limetype}/${id}/`;
|
|
39
54
|
const response: NodeResponse<void> = await callLimeApi(
|
|
40
55
|
nodeContext,
|
|
41
56
|
'DELETE',
|
|
@@ -48,63 +63,80 @@ export async function deleteLimeObject(
|
|
|
48
63
|
...response,
|
|
49
64
|
metadata: {
|
|
50
65
|
...response.metadata,
|
|
51
|
-
|
|
66
|
+
limetype: limetype,
|
|
52
67
|
id: id,
|
|
53
68
|
},
|
|
54
69
|
};
|
|
55
70
|
}
|
|
56
71
|
|
|
57
|
-
export async function
|
|
72
|
+
export async function getLimeobject(
|
|
58
73
|
nodeContext: IAllExecuteFunctions,
|
|
59
|
-
|
|
74
|
+
limetype: string,
|
|
60
75
|
id: string
|
|
61
|
-
): Promise<NodeResponse<
|
|
62
|
-
const url = `${LIMEOBJECT_URL}${
|
|
63
|
-
const response = await callLimeApi(
|
|
76
|
+
): Promise<NodeResponse<Limeobject>> {
|
|
77
|
+
const url = `${LIMEOBJECT_URL}${limetype}/${id}/`;
|
|
78
|
+
const response = await callLimeApi<LimeobjectCrmApiResponse>(
|
|
79
|
+
nodeContext,
|
|
80
|
+
'GET',
|
|
81
|
+
url
|
|
82
|
+
);
|
|
64
83
|
|
|
65
|
-
if (response.success)
|
|
84
|
+
if (response.success)
|
|
85
|
+
return {
|
|
86
|
+
success: true,
|
|
87
|
+
data: removeKeys(response.data, ['_links']),
|
|
88
|
+
};
|
|
66
89
|
|
|
67
90
|
return {
|
|
68
91
|
...response,
|
|
69
92
|
metadata: {
|
|
70
93
|
...response.metadata,
|
|
71
|
-
|
|
94
|
+
limetype: limetype,
|
|
72
95
|
id: id,
|
|
73
96
|
},
|
|
74
97
|
};
|
|
75
98
|
}
|
|
76
99
|
|
|
77
|
-
export async function
|
|
100
|
+
export async function updateLimeobject(
|
|
78
101
|
nodeContext: IAllExecuteFunctions,
|
|
79
|
-
|
|
102
|
+
limetype: string,
|
|
80
103
|
id: string,
|
|
81
104
|
data: object
|
|
82
|
-
): Promise<NodeResponse<
|
|
83
|
-
const url = `${LIMEOBJECT_URL}${
|
|
84
|
-
const response = await callLimeApi(
|
|
85
|
-
|
|
86
|
-
|
|
105
|
+
): Promise<NodeResponse<Limeobject>> {
|
|
106
|
+
const url = `${LIMEOBJECT_URL}${limetype}/${id}/`;
|
|
107
|
+
const response = await callLimeApi<LimeobjectCrmApiResponse>(
|
|
108
|
+
nodeContext,
|
|
109
|
+
'PUT',
|
|
110
|
+
url,
|
|
111
|
+
{
|
|
112
|
+
body: data,
|
|
113
|
+
}
|
|
114
|
+
);
|
|
87
115
|
|
|
88
|
-
if (response.success)
|
|
116
|
+
if (response.success)
|
|
117
|
+
return {
|
|
118
|
+
success: true,
|
|
119
|
+
data: removeKeys(response.data, ['_links']),
|
|
120
|
+
};
|
|
89
121
|
|
|
90
122
|
return {
|
|
91
123
|
...response,
|
|
92
124
|
metadata: {
|
|
93
125
|
...response.metadata,
|
|
94
|
-
|
|
126
|
+
limetype: limetype,
|
|
95
127
|
id: id,
|
|
96
128
|
},
|
|
97
129
|
};
|
|
98
130
|
}
|
|
99
131
|
|
|
100
|
-
async function
|
|
132
|
+
async function _searchLimeobjectWithLimit(
|
|
101
133
|
nodeContext: IAllExecuteFunctions,
|
|
102
134
|
url: string,
|
|
103
135
|
limit: number,
|
|
104
136
|
offset: number,
|
|
105
137
|
qs: IDataObject
|
|
106
|
-
): Promise<NodeResponse<
|
|
107
|
-
const returnData = [];
|
|
138
|
+
): Promise<NodeResponse<FetchManyLimeobjectsApiResponse>> {
|
|
139
|
+
const returnData: LimeobjectCrmApiResponse[] = [];
|
|
108
140
|
let hasMoreData = true;
|
|
109
141
|
let currentOffset = Math.max(0, offset);
|
|
110
142
|
const pageLimit = 50;
|
|
@@ -113,7 +145,7 @@ async function _searchLimeObjectWithLimit(
|
|
|
113
145
|
qs._limit = Math.min(limit, pageLimit);
|
|
114
146
|
qs._offset = currentOffset;
|
|
115
147
|
|
|
116
|
-
const response = await callLimeApi<
|
|
148
|
+
const response = await callLimeApi<FetchManyLimeobjectsApiResponse>(
|
|
117
149
|
nodeContext,
|
|
118
150
|
'GET',
|
|
119
151
|
url,
|
|
@@ -143,16 +175,16 @@ async function _searchLimeObjectWithLimit(
|
|
|
143
175
|
};
|
|
144
176
|
}
|
|
145
177
|
|
|
146
|
-
export async function
|
|
178
|
+
export async function fetchManyLimeobjects(
|
|
147
179
|
nodeContext: IAllExecuteFunctions,
|
|
148
|
-
|
|
180
|
+
limetype: string,
|
|
149
181
|
searchField: string,
|
|
150
182
|
searchTerm: string,
|
|
151
183
|
limit: number,
|
|
152
184
|
offset: number,
|
|
153
185
|
sortField: string | null
|
|
154
|
-
): Promise<NodeResponse<
|
|
155
|
-
const url = `${LIMEOBJECT_URL}${
|
|
186
|
+
): Promise<NodeResponse<Limeobject[]>> {
|
|
187
|
+
const url = `${LIMEOBJECT_URL}${limetype}/`;
|
|
156
188
|
const qs: IDataObject = {
|
|
157
189
|
...(searchField && searchTerm && { [searchField]: searchTerm }),
|
|
158
190
|
...(offset != null && offset > 0 && { _offset: offset }),
|
|
@@ -161,7 +193,7 @@ export async function fetchManyLimeObjects(
|
|
|
161
193
|
|
|
162
194
|
let response;
|
|
163
195
|
if (limit) {
|
|
164
|
-
response = await
|
|
196
|
+
response = await _searchLimeobjectWithLimit(
|
|
165
197
|
nodeContext,
|
|
166
198
|
url,
|
|
167
199
|
limit,
|
|
@@ -169,7 +201,7 @@ export async function fetchManyLimeObjects(
|
|
|
169
201
|
qs
|
|
170
202
|
);
|
|
171
203
|
} else {
|
|
172
|
-
response = await callLimeApi<
|
|
204
|
+
response = await callLimeApi<FetchManyLimeobjectsApiResponse>(
|
|
173
205
|
nodeContext,
|
|
174
206
|
'GET',
|
|
175
207
|
url,
|
|
@@ -182,7 +214,10 @@ export async function fetchManyLimeObjects(
|
|
|
182
214
|
if (response.success) {
|
|
183
215
|
return {
|
|
184
216
|
success: true,
|
|
185
|
-
data:
|
|
217
|
+
data:
|
|
218
|
+
response.data?._embedded.limeobjects.map((limeobject) =>
|
|
219
|
+
removeKeys(limeobject, ['_links'])
|
|
220
|
+
) ?? [],
|
|
186
221
|
};
|
|
187
222
|
}
|
|
188
223
|
return {
|
|
@@ -191,7 +226,7 @@ export async function fetchManyLimeObjects(
|
|
|
191
226
|
status: response.status,
|
|
192
227
|
metadata: {
|
|
193
228
|
...response.metadata,
|
|
194
|
-
|
|
229
|
+
limetype: limetype,
|
|
195
230
|
},
|
|
196
231
|
};
|
|
197
232
|
}
|
|
@@ -1,63 +1,112 @@
|
|
|
1
1
|
import { callLimeApi } from '.';
|
|
2
2
|
import { IAllExecuteFunctions } from 'n8n-workflow';
|
|
3
|
-
import {
|
|
3
|
+
import { Limetype, LimetypeProperty } from '../model';
|
|
4
4
|
import { NodeResponse } from '../../nodeResponse';
|
|
5
|
+
import { removeKeys } from './commons';
|
|
5
6
|
|
|
6
7
|
const LIMETYPE_URL = '/api/v1/limetype/';
|
|
7
8
|
|
|
8
|
-
interface
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
interface LimetypePropertyApiResponse {
|
|
10
|
+
name: string;
|
|
11
|
+
_links?: object;
|
|
12
|
+
_embedded?: object;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface LimetypeCrmApiResponse {
|
|
16
|
+
name: string;
|
|
17
|
+
localname?: {
|
|
18
|
+
singular?: string;
|
|
19
|
+
plural?: string;
|
|
20
|
+
};
|
|
21
|
+
_embedded: {
|
|
22
|
+
properties: LimetypePropertyApiResponse[];
|
|
23
|
+
};
|
|
24
|
+
_links: object;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface LimetypesCrmApiResponse {
|
|
28
|
+
_embedded: {
|
|
29
|
+
limetypes: LimetypeCrmApiResponse[];
|
|
30
|
+
_links: object;
|
|
11
31
|
};
|
|
12
32
|
}
|
|
13
33
|
|
|
14
|
-
interface
|
|
34
|
+
interface LimetypePropertiesApiResponse {
|
|
15
35
|
_embedded: {
|
|
16
|
-
properties:
|
|
36
|
+
properties: LimetypeCrmApiResponse[];
|
|
17
37
|
};
|
|
18
38
|
}
|
|
19
39
|
|
|
20
|
-
|
|
40
|
+
function deserializeLimetype(limetype: LimetypeCrmApiResponse): Limetype {
|
|
41
|
+
return {
|
|
42
|
+
...removeKeys(limetype, ['_links', '_embedded']),
|
|
43
|
+
properties: limetype._embedded.properties.map((property) =>
|
|
44
|
+
removeKeys(property, ['_links'])
|
|
45
|
+
),
|
|
46
|
+
} as Limetype;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function getLimetypesFromApi(
|
|
21
50
|
nodeContext: IAllExecuteFunctions
|
|
22
|
-
): Promise<NodeResponse<
|
|
23
|
-
const response = await callLimeApi<
|
|
51
|
+
): Promise<NodeResponse<Limetype[]>> {
|
|
52
|
+
const response = await callLimeApi<LimetypesCrmApiResponse>(
|
|
24
53
|
nodeContext,
|
|
25
54
|
'GET',
|
|
26
|
-
LIMETYPE_URL
|
|
55
|
+
LIMETYPE_URL,
|
|
56
|
+
{
|
|
57
|
+
qs: {
|
|
58
|
+
_embed: 'limetypes.properties',
|
|
59
|
+
},
|
|
60
|
+
}
|
|
27
61
|
);
|
|
28
62
|
if (response.success) {
|
|
29
63
|
return {
|
|
30
64
|
success: true,
|
|
31
|
-
data:
|
|
65
|
+
data:
|
|
66
|
+
response.data._embedded?.limetypes.map(deserializeLimetype) ||
|
|
67
|
+
[],
|
|
32
68
|
};
|
|
33
69
|
}
|
|
34
70
|
return response;
|
|
35
71
|
}
|
|
36
72
|
|
|
37
|
-
export async function
|
|
73
|
+
export async function getLimetype(
|
|
38
74
|
nodeContext: IAllExecuteFunctions,
|
|
39
|
-
|
|
40
|
-
): Promise<NodeResponse<
|
|
41
|
-
const url = `${LIMETYPE_URL}${
|
|
42
|
-
const response = await callLimeApi<
|
|
75
|
+
limetype: string
|
|
76
|
+
): Promise<NodeResponse<Limetype>> {
|
|
77
|
+
const url = `${LIMETYPE_URL}${limetype}/`;
|
|
78
|
+
const response = await callLimeApi<LimetypeCrmApiResponse>(
|
|
79
|
+
nodeContext,
|
|
80
|
+
'GET',
|
|
81
|
+
url,
|
|
82
|
+
{
|
|
83
|
+
qs: {
|
|
84
|
+
_embed: 'properties',
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
);
|
|
43
88
|
|
|
44
|
-
if (response.success)
|
|
89
|
+
if (response.success)
|
|
90
|
+
return {
|
|
91
|
+
success: true,
|
|
92
|
+
data: deserializeLimetype(response.data),
|
|
93
|
+
};
|
|
45
94
|
|
|
46
95
|
return {
|
|
47
96
|
...response,
|
|
48
97
|
metadata: {
|
|
49
98
|
...response.metadata,
|
|
50
|
-
limetype:
|
|
99
|
+
limetype: limetype,
|
|
51
100
|
},
|
|
52
101
|
};
|
|
53
102
|
}
|
|
54
103
|
|
|
55
104
|
export async function getProperties(
|
|
56
105
|
nodeContext: IAllExecuteFunctions,
|
|
57
|
-
|
|
58
|
-
): Promise<NodeResponse<
|
|
59
|
-
const url = `${LIMETYPE_URL}${
|
|
60
|
-
const response = await callLimeApi<
|
|
106
|
+
limetype: string
|
|
107
|
+
): Promise<NodeResponse<LimetypeProperty[]>> {
|
|
108
|
+
const url = `${LIMETYPE_URL}${limetype}/`;
|
|
109
|
+
const response = await callLimeApi<LimetypePropertiesApiResponse>(
|
|
61
110
|
nodeContext,
|
|
62
111
|
'GET',
|
|
63
112
|
url,
|
|
@@ -71,7 +120,14 @@ export async function getProperties(
|
|
|
71
120
|
if (response.success) {
|
|
72
121
|
return {
|
|
73
122
|
success: true,
|
|
74
|
-
data:
|
|
123
|
+
data:
|
|
124
|
+
response.data?._embedded.properties.map(
|
|
125
|
+
(property) =>
|
|
126
|
+
removeKeys(property, [
|
|
127
|
+
'_links',
|
|
128
|
+
'_embedded',
|
|
129
|
+
]) as LimetypeProperty
|
|
130
|
+
) || [],
|
|
75
131
|
};
|
|
76
132
|
}
|
|
77
133
|
|
|
@@ -79,7 +135,7 @@ export async function getProperties(
|
|
|
79
135
|
...response,
|
|
80
136
|
metadata: {
|
|
81
137
|
...response.metadata,
|
|
82
|
-
limetype:
|
|
138
|
+
limetype: limetype,
|
|
83
139
|
},
|
|
84
140
|
};
|
|
85
141
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@limetech/n8n-nodes-lime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "n8n node to connect to Lime CRM",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "tsc &&
|
|
8
|
+
"build": "tsc && copyfiles \"nodes/**/*.svg\" dist",
|
|
9
9
|
"dev": "tsc --watch",
|
|
10
10
|
"dev:reload": "nodemon --watch dist --exec 'cp -R dist/* ~/.n8n/custom/dist/'",
|
|
11
11
|
"watch": "concurrently \"npm run dev\" \"npm run dev:reload\"",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"@typescript-eslint/eslint-plugin": "^8.38.0",
|
|
49
49
|
"@typescript-eslint/parser": "^8.38.0",
|
|
50
50
|
"concurrently": "^7.0.0",
|
|
51
|
+
"copyfiles": "^2.4.1",
|
|
51
52
|
"eslint": "^9.32.0",
|
|
52
53
|
"eslint-config-prettier": "^10.1.8",
|
|
53
54
|
"eslint-plugin-n8n-nodes-base": "^1.16.1",
|
|
@@ -70,6 +71,6 @@
|
|
|
70
71
|
"ws": "^8.18.3"
|
|
71
72
|
},
|
|
72
73
|
"peerDependencies": {
|
|
73
|
-
"n8n-workflow": "
|
|
74
|
+
"n8n-workflow": "^1.109.0"
|
|
74
75
|
}
|
|
75
76
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
### n8n Scripts
|
|
2
|
+
|
|
3
|
+
Utility scripts to batch upload, download and transfer workflows as JSON data to and from an n8n instance via
|
|
4
|
+
its REST API.
|
|
5
|
+
|
|
6
|
+
=========================================================================================
|
|
7
|
+
### Features
|
|
8
|
+
- download: Fetch items workflows from n8n and store locally.
|
|
9
|
+
- upload: Push local workflows to n8n.
|
|
10
|
+
- transfer: Combine download then upload for migrating between two instances without local storage
|
|
11
|
+
- cli: Unified command line entrypoint wrapping the download and upload operations.
|
|
12
|
+
|
|
13
|
+
=========================================================================================
|
|
14
|
+
### Installation
|
|
15
|
+
```bash
|
|
16
|
+
poetry install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
=========================================================================================
|
|
20
|
+
### Usage
|
|
21
|
+
|
|
22
|
+
#### Interactive Mode
|
|
23
|
+
```bash
|
|
24
|
+
poetry run python ./main.py
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The api_key can also be provided in files [root directory]:
|
|
28
|
+
- `api_key_download.txt` for download operations
|
|
29
|
+
- `api_key_upload.txt` for upload operations
|
|
30
|
+
|
|
31
|
+
#### CLI Mode
|
|
32
|
+
Download
|
|
33
|
+
```bash
|
|
34
|
+
poetry run python ./cli.py download --instance_url <INSTANCE_URL> --api_key <API_KEY> --folder_path <FOLDER_PATH>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Upload
|
|
38
|
+
```bash
|
|
39
|
+
poetry run python ./cli.py upload --instance_url <INSTANCE_URL> --api_key <API_KEY> --folder_path <FOLDER_PATH>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The api_key can also be provided via the N8N_API_KEY environment variable.
|
|
File without changes
|
|
File without changes
|