@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.
Files changed (51) hide show
  1. package/.github/workflows/lint.yml +1 -1
  2. package/.github/workflows/release.yml +16 -2
  3. package/.github/workflows/test-and-build.yml +0 -15
  4. package/CHANGELOG.md +35 -2
  5. package/nodes/errorHandling.ts +60 -0
  6. package/nodes/lime-crm/LimeCrmNode.node.ts +8 -0
  7. package/nodes/lime-crm/LimeCrmTrigger.node.ts +19 -5
  8. package/nodes/lime-crm/methods/getLimetypeProperties.ts +3 -1
  9. package/nodes/lime-crm/methods/getLimetypes.ts +2 -1
  10. package/nodes/lime-crm/methods/index.ts +5 -0
  11. package/nodes/lime-crm/methods/resourceMapping.ts +141 -0
  12. package/nodes/lime-crm/models/limetype.ts +18 -0
  13. package/nodes/lime-crm/resources/admin/index.ts +9 -4
  14. package/nodes/lime-crm/resources/admin/operations/getManyUsers.operation.ts +10 -2
  15. package/nodes/lime-crm/resources/admin/operations/getSingleUser.operation.ts +14 -15
  16. package/nodes/lime-crm/resources/data/index.ts +15 -6
  17. package/nodes/lime-crm/resources/data/operations/createSingleObject.operation.ts +25 -71
  18. package/nodes/lime-crm/resources/data/operations/deleteSingleObject.operation.ts +7 -2
  19. package/nodes/lime-crm/resources/data/operations/getManyObjects.operation.ts +6 -2
  20. package/nodes/lime-crm/resources/data/operations/getSingleFile.operation.ts +15 -3
  21. package/nodes/lime-crm/resources/data/operations/getSingleObject.operation.ts +15 -6
  22. package/nodes/lime-crm/resources/data/operations/updateSingleObject.operation.ts +41 -57
  23. package/nodes/lime-crm/resources/metadata/index.ts +7 -3
  24. package/nodes/lime-crm/resources/metadata/operations/getAllLimetypes.operation.ts +6 -2
  25. package/nodes/lime-crm/resources/metadata/operations/getSingleFileMetadata.operation.ts +18 -15
  26. package/nodes/lime-crm/resources/metadata/operations/getSingleLimetype.operation.ts +8 -3
  27. package/nodes/lime-crm/transport/commons.ts +34 -20
  28. package/nodes/lime-crm/transport/files.ts +72 -47
  29. package/nodes/lime-crm/transport/limeQuery.ts +2 -2
  30. package/nodes/lime-crm/transport/limeobjects.ts +22 -10
  31. package/nodes/lime-crm/transport/limetypes.ts +37 -16
  32. package/nodes/lime-crm/transport/users.ts +74 -38
  33. package/nodes/lime-crm/transport/webhooks.ts +5 -4
  34. package/nodes/lime-crm/utils/files.ts +27 -10
  35. package/nodes/lime-crm/utils/index.ts +1 -1
  36. package/nodes/response.ts +41 -3
  37. package/package.json +4 -2
  38. package/tests/nodes/lime-crm/methods.spec.ts +91 -0
  39. package/tests/nodes/lime-crm/utils.spec.ts +60 -25
  40. package/nodes/lime-crm/utils/propertyAdapters.ts +0 -75
  41. package/restore_script/README +0 -42
  42. package/restore_script/api_key_upload.txt +0 -0
  43. package/restore_script/cli.py +0 -73
  44. package/restore_script/download.py +0 -73
  45. package/restore_script/main.py +0 -19
  46. package/restore_script/poetry.lock +0 -162
  47. package/restore_script/pyproject.toml +0 -15
  48. package/restore_script/transfer.py +0 -41
  49. package/restore_script/upload.py +0 -66
  50. package/restore_script/utils.py +0 -42
  51. /package/{restore_script/api_key_download.txt → Dockerfile} +0 -0
@@ -4,7 +4,7 @@ on:
4
4
  pull_request:
5
5
  push:
6
6
  branches:
7
- - master
7
+ - main
8
8
 
9
9
  jobs:
10
10
  lint:
@@ -1,4 +1,4 @@
1
- name: Release and Push to ECR
1
+ name: Release and Push to NPM Registry
2
2
 
3
3
  on:
4
4
  push:
@@ -32,4 +32,18 @@ jobs:
32
32
  echo "version=$VERSION" >> $GITHUB_OUTPUT
33
33
  env:
34
34
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
35
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
36
+
37
+ push-to-npm:
38
+ name: Push package to NPM
39
+ runs-on: ubuntu-latest
40
+ needs: release
41
+ permissions:
42
+ id-token: write
43
+ contents: read
44
+ steps:
45
+ - name: Checkout repository
46
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
47
+ - run: npm ci
48
+ - name: Publish
49
+ run: npm publish
@@ -30,18 +30,3 @@ jobs:
30
30
 
31
31
  - name: Run tests
32
32
  run: npm run test
33
-
34
- docker-build:
35
- name: Build docker image
36
- runs-on: ubuntu-latest
37
-
38
- steps:
39
- - name: Checkout code
40
- uses: actions/checkout@v4
41
-
42
- - name: Set up Docker Buildx
43
- uses: docker/setup-buildx-action@v3
44
-
45
- - name: Test Docker build
46
- run: |
47
- docker build .
package/CHANGELOG.md CHANGED
@@ -1,9 +1,42 @@
1
- ## [2.3.1-dev.1](https://github.com/Lundalogik/lime-n8n/compare/v2.3.0...v2.3.1-dev.1) (2025-12-01)
1
+ # [2.5.0](https://github.com/Lundalogik/lime-n8n/compare/v2.4.0...v2.5.0) (2026-01-08)
2
2
 
3
3
 
4
4
  ### Bug Fixes
5
5
 
6
- * create an npm package out of repo ([ec68ddc](https://github.com/Lundalogik/lime-n8n/commit/ec68ddc0fa6c5bf0e9b4302877c1fe64599ea01a))
6
+ * fix npm release ([f5ea4a9](https://github.com/Lundalogik/lime-n8n/commit/f5ea4a9938893726da36a1a7320bcf3acbafe0f1))
7
+
8
+
9
+ ### Features
10
+
11
+ * create an npm package out of repo ([e65a950](https://github.com/Lundalogik/lime-n8n/commit/e65a950ff42711a6c6fb624cb903d979a6ef8d4f))
12
+
13
+ # [2.4.0](https://github.com/Lundalogik/lime-n8n/compare/v2.3.3...v2.4.0) (2025-12-12)
14
+
15
+
16
+ ### Features
17
+
18
+ * add resourceMapper to create single object ([ba1a537](https://github.com/Lundalogik/lime-n8n/commit/ba1a53774cd05691d9bdd3b70eec768e1cbd4cc6))
19
+
20
+ ## [2.3.3](https://github.com/Lundalogik/lime-n8n/compare/v2.3.2...v2.3.3) (2025-12-09)
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * fix error handling in n8n ([1e6b878](https://github.com/Lundalogik/lime-n8n/commit/1e6b8782629a16117c7cac3f62b043cf897a2a96))
26
+
27
+ ## [2.3.2](https://github.com/Lundalogik/lime-n8n/compare/v2.3.1...v2.3.2) (2025-12-08)
28
+
29
+
30
+ ### Bug Fixes
31
+
32
+ * change timezone to utc ([4ab309f](https://github.com/Lundalogik/lime-n8n/commit/4ab309fc0b9a37743ea398ec8cf594507be7f1be))
33
+
34
+ ## [2.3.1](https://github.com/Lundalogik/lime-n8n/compare/v2.3.0...v2.3.1) (2025-12-02)
35
+
36
+
37
+ ### Bug Fixes
38
+
39
+ * fix master reference in lint.yml ([0a91f70](https://github.com/Lundalogik/lime-n8n/commit/0a91f7092de81139294328f6cb114593c963bc69))
7
40
 
8
41
  # [2.3.0](https://github.com/Lundalogik/lime-n8n/compare/v2.2.0...v2.3.0) (2025-11-21)
9
42
 
@@ -0,0 +1,60 @@
1
+ import {
2
+ IExecuteFunctions,
3
+ IAllExecuteFunctions,
4
+ NodeApiError,
5
+ NodeOperationError,
6
+ JsonObject,
7
+ } from 'n8n-workflow';
8
+
9
+ /**
10
+ * Type guard checking if the class conforms to {@link IExecuteFunctions}
11
+ * interface
12
+ * @param nodeContext - a subclass of n8n's FunctionsBase interface
13
+ */
14
+ function isIExecuteFunctions(
15
+ nodeContext: IAllExecuteFunctions
16
+ ): nodeContext is IExecuteFunctions {
17
+ return (nodeContext as IExecuteFunctions).continueOnFail !== undefined;
18
+ }
19
+
20
+ /**
21
+ * Wrapper for the error data used in Lime workflows
22
+ */
23
+ export type WorkflowErrorContext = {
24
+ message: string;
25
+ } & JsonObject;
26
+
27
+ /**
28
+ * Structure for unsuccessful response used in communication layer.
29
+ */
30
+ export type ErrorResponse = {
31
+ success: false;
32
+ data: { error: WorkflowErrorContext };
33
+ };
34
+
35
+ /**
36
+ * Function which handles how are the errors handled in n8n workflows. It
37
+ * either throws an error or returns the error data, depending on the
38
+ * `continue on Error` flag.
39
+ * @param nodeContext - the context of a Node - we need to check if it's a
40
+ * subclass of {@link IExecuteFunctions}
41
+ * @param errorContext - the data of the error we want to return to the user
42
+ * @param isApiError - flag checking if the error is connected to the external
43
+ * API or internal N8N's logic - based on it we either throw {@link NodeApiError}
44
+ * or {@link NodeOperationError}
45
+ */
46
+ export function handleWorkflowError(
47
+ nodeContext: IAllExecuteFunctions,
48
+ errorContext: WorkflowErrorContext,
49
+ isApiError: boolean = false
50
+ ): ErrorResponse {
51
+ if (isIExecuteFunctions(nodeContext) && nodeContext.continueOnFail()) {
52
+ return {
53
+ success: false,
54
+ data: { error: errorContext },
55
+ };
56
+ } else if (isApiError) {
57
+ throw new NodeApiError(nodeContext.getNode(), errorContext);
58
+ }
59
+ throw new NodeOperationError(nodeContext.getNode(), errorContext.message);
60
+ }
@@ -24,6 +24,8 @@ import {
24
24
  getLimetypeProperties,
25
25
  getLimetypes,
26
26
  getNoHasManyProperties,
27
+ getCreateMappingColumns,
28
+ getUpdateMappingColumns,
27
29
  } from './methods';
28
30
 
29
31
  /**
@@ -137,6 +139,8 @@ export class LimeCrmNode implements INodeType {
137
139
  * - {@link getFileProperties}
138
140
  * - {@link getLimetypeProperties}
139
141
  * - {@link getNoHasManyProperties}
142
+ * - {@link getUpdateMappingColumns}
143
+ * - {@link getCreateMappingColumns}
140
144
  */
141
145
  methods = {
142
146
  loadOptions: {
@@ -145,6 +149,10 @@ export class LimeCrmNode implements INodeType {
145
149
  getFileProperties,
146
150
  getNoHasManyProperties,
147
151
  },
152
+ resourceMapping: {
153
+ getUpdateMappingColumns,
154
+ getCreateMappingColumns,
155
+ },
148
156
  };
149
157
 
150
158
  /**
@@ -8,6 +8,7 @@ import {
8
8
  NodeOperationError,
9
9
  LoggerProxy as Logger,
10
10
  NodeConnectionTypes,
11
+ NodeApiError,
11
12
  } from 'n8n-workflow';
12
13
 
13
14
  import { LIME_CRM_API_CREDENTIAL_KEY } from './models';
@@ -173,7 +174,7 @@ export class LimeCrmTrigger implements INodeType {
173
174
  Logger.warn(
174
175
  `There was en error while getting a webhook from Lime CRM: ${error}`
175
176
  );
176
- throw new NodeOperationError(this.getNode(), error);
177
+ throw new NodeApiError(this.getNode(), error);
177
178
  }
178
179
  return true;
179
180
  },
@@ -193,8 +194,14 @@ export class LimeCrmTrigger implements INodeType {
193
194
  // but it's only suited for production environment
194
195
  const existingSubscriptionResponse =
195
196
  await listSubscriptionsWithExistingData(this, webhook);
197
+ if (!existingSubscriptionResponse.success) {
198
+ throw new NodeApiError(this.getNode(), {
199
+ message:
200
+ existingSubscriptionResponse.data.error.message,
201
+ });
202
+ }
196
203
 
197
- if (existingSubscriptionResponse.length === 0) {
204
+ if (existingSubscriptionResponse.data.length === 0) {
198
205
  const credentials = await this.getCredentials(
199
206
  LIME_CRM_API_CREDENTIAL_KEY
200
207
  );
@@ -208,8 +215,15 @@ export class LimeCrmTrigger implements INodeType {
208
215
  webhookCreateData
209
216
  );
210
217
 
211
- const subscriptionId = createSubscriptionResponse.id;
212
- const events = createSubscriptionResponse.events;
218
+ if (!createSubscriptionResponse.success) {
219
+ throw new NodeApiError(this.getNode(), {
220
+ message:
221
+ createSubscriptionResponse.data.error.message,
222
+ });
223
+ }
224
+
225
+ const subscriptionId = createSubscriptionResponse.data.id;
226
+ const events = createSubscriptionResponse.data.events;
213
227
 
214
228
  webhook.data.webhookId = subscriptionId;
215
229
  webhook.data.webhookEvents = events;
@@ -218,7 +232,7 @@ export class LimeCrmTrigger implements INodeType {
218
232
  );
219
233
  return true;
220
234
  } else {
221
- const limeWebhook = existingSubscriptionResponse[0];
235
+ const limeWebhook = existingSubscriptionResponse.data[0];
222
236
  webhook.data.webhookId = limeWebhook.id;
223
237
  webhook.data.webhookEvents = limeWebhook.events;
224
238
  Logger.info(
@@ -22,7 +22,9 @@ async function fetchAllProperties(nodeContext: ILoadOptionsFunctions) {
22
22
  Logger.info(`Fetching file properties for Lime type: ${limetype}`);
23
23
  if (!limetype) return [];
24
24
  try {
25
- return await getProperties(nodeContext, limetype);
25
+ const response = await getProperties(nodeContext, limetype);
26
+ if (!response.success) return [];
27
+ return response.data;
26
28
  } catch (error) {
27
29
  Logger.warn(`There was a problem with fetching properties: ${error}`);
28
30
  return [];
@@ -14,8 +14,9 @@ export async function getLimetypes(
14
14
  ): Promise<INodePropertyOptions[]> {
15
15
  const data: INodePropertyOptions[] = [];
16
16
  const response = await getLimetypesFromApi(this);
17
+ if (!response.success) return [];
17
18
 
18
- for (const limetype of response) {
19
+ for (const limetype of response.data) {
19
20
  data.push({
20
21
  name: limetype.localname?.singular || limetype.name,
21
22
  value: limetype.name,
@@ -5,3 +5,8 @@ export {
5
5
  getLimetypeProperties,
6
6
  getNoHasManyProperties,
7
7
  } from './getLimetypeProperties';
8
+ export {
9
+ getCreateMappingColumns,
10
+ getUpdateMappingColumns,
11
+ parseResourceMapperFields,
12
+ } from './resourceMapping';
@@ -0,0 +1,141 @@
1
+ import {
2
+ FieldType,
3
+ ILoadOptionsFunctions,
4
+ ResourceMapperFields,
5
+ LoggerProxy as Logger,
6
+ IExecuteFunctions,
7
+ IDataObject,
8
+ ResourceMapperValue,
9
+ } from 'n8n-workflow';
10
+ import { getProperties } from '../transport';
11
+ import { LimetypeProperty } from '../models';
12
+
13
+ /**
14
+ * A map of Lime CRM field types to n8n native types
15
+ */
16
+ const LimeCrmTypeToFieldType = new Map(
17
+ Object.entries({
18
+ option: 'options',
19
+ yesno: 'boolean',
20
+ decimal: 'number',
21
+ number: 'number',
22
+ })
23
+ );
24
+
25
+ /**
26
+ * Function which maps Lime CRM to n8n types using the map above. If the type
27
+ * is not declared in a map, string is used.
28
+ * @param limeCrmType
29
+ * @returns n8n native {@link FieldType}
30
+ */
31
+ function mapLimeCrmType(limeCrmType: string): FieldType {
32
+ return (LimeCrmTypeToFieldType.get(limeCrmType) as FieldType) || 'string';
33
+ }
34
+
35
+ /**
36
+ * Get a `length` addition to the input headers when there's a string field
37
+ *
38
+ * @param property - a {@link LimetypeProperty}
39
+ * @returns a string with length wrapped in quotes or an empty string
40
+ */
41
+ function getPropertyLength(property: LimetypeProperty): string {
42
+ return property.type === 'string' ? `(${property.length})` : '';
43
+ }
44
+
45
+ /**
46
+ * Base function to get the description of ResourceMapper fields
47
+ * @param nodeContext
48
+ * @param mode - either `create` or `update` - based on this flag a `required`
49
+ * @param limetype - name of a limetype we are creating or updating
50
+ * property is set
51
+ */
52
+ async function getMappingColumns(
53
+ nodeContext: ILoadOptionsFunctions,
54
+ mode: 'create' | 'update',
55
+ limetype: string
56
+ ): Promise<ResourceMapperFields> {
57
+ const propertiesResponse = await getProperties(nodeContext, limetype);
58
+ if (!propertiesResponse.success) {
59
+ Logger.error(
60
+ `There was an error with fetching properties: ${JSON.stringify(propertiesResponse.data)}`
61
+ );
62
+ return {
63
+ fields: [],
64
+ };
65
+ }
66
+ const noRelationProperties = propertiesResponse.data.filter(
67
+ (property) => property.type !== 'hasmany'
68
+ );
69
+
70
+ const fields = noRelationProperties.map((property) => {
71
+ const propertyLengthDescription = getPropertyLength(property);
72
+ return {
73
+ id: property.name,
74
+ displayName: `${property.localname} [${property.type}${propertyLengthDescription}]`,
75
+ required: mode === 'create' ? property.required : false,
76
+ defaultMatch: false,
77
+ display: true,
78
+ type: mapLimeCrmType(property.type),
79
+ options:
80
+ property.type === 'option' && property.options
81
+ ? property.options
82
+ .filter((option) => !option.inactive)
83
+ .map((option) => {
84
+ return {
85
+ value: option.key,
86
+ name: option.text,
87
+ };
88
+ })
89
+ : undefined,
90
+ };
91
+ });
92
+ return {
93
+ fields: fields.sort((a, b) => {
94
+ if (a.required !== b.required) {
95
+ return a.required ? -1 : 1;
96
+ }
97
+ return a.displayName.localeCompare(b.displayName);
98
+ }),
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Parse resource mapper fields from n8n workflow
104
+ * @param context - Node execution context
105
+ * @param i - The index of the current item in the workflow execution
106
+ * @param inputName - name of the resource mapper input
107
+ * @returns IDataObject - parsed data from resource mapper
108
+ */
109
+
110
+ export function parseResourceMapperFields(
111
+ context: IExecuteFunctions,
112
+ i: number,
113
+ inputName: string
114
+ ): IDataObject {
115
+ const propertiesInput = context.getNodeParameter(
116
+ inputName,
117
+ i
118
+ ) as ResourceMapperValue;
119
+
120
+ return propertiesInput.value as IDataObject;
121
+ }
122
+
123
+ /**
124
+ * Method for getting resource mapper fields in `create` mode
125
+ */
126
+ export async function getCreateMappingColumns(
127
+ this: ILoadOptionsFunctions
128
+ ): Promise<ResourceMapperFields> {
129
+ const limetype = this.getNodeParameter('limetype') as string;
130
+ return getMappingColumns(this, 'create', limetype);
131
+ }
132
+
133
+ /**
134
+ * Method for getting resource mapper fields in `update` mode
135
+ */
136
+ export async function getUpdateMappingColumns(
137
+ this: ILoadOptionsFunctions
138
+ ): Promise<ResourceMapperFields> {
139
+ const limetype = this.getNodeParameter('limetype') as string;
140
+ return getMappingColumns(this, 'update', limetype);
141
+ }
@@ -1,11 +1,26 @@
1
1
  import { APIResponseValue } from './constants';
2
2
 
3
+ /**
4
+ * Limetype option used only for fields with `option` type.
5
+ * @property key - ID of an option, used as a value for POST/PUT requests in API
6
+ * @property text - display name of an option
7
+ * @property inactive - flag describing whether the property is used or not
8
+ */
9
+ type LimetypePropertyOption = {
10
+ key: string;
11
+ text: string;
12
+ inactive: boolean;
13
+ };
14
+
3
15
  /**
4
16
  * Representation of a property of a Limetype.
5
17
  *
6
18
  * @property name - The internal name of the property
7
19
  * @property localname - The display name of the property
8
20
  * @property type - The type of the property (e.g., string, file, hasmany)
21
+ * @property required - describes whether a property is required or not
22
+ * @property options - a set of {@link LimetypePropertyOption} used only for
23
+ * fields with type `option`.
9
24
  *
10
25
  * @public
11
26
  * @group Models
@@ -14,6 +29,9 @@ export type LimetypeProperty = {
14
29
  name: string;
15
30
  localname: string;
16
31
  type: string;
32
+ required: boolean;
33
+ length?: number;
34
+ options?: LimetypePropertyOption[];
17
35
  } & Record<string, APIResponseValue>;
18
36
 
19
37
  /**
@@ -68,10 +68,15 @@ export async function adminOperations(
68
68
  switch (operation) {
69
69
  case 'getManyUsers': {
70
70
  const result = await operations.getManyUsers.execute.call(this, i);
71
-
72
- return result.map((item: User) => ({
73
- json: item,
74
- }));
71
+ if (Array.isArray(result)) {
72
+ return result.map((item: User) => ({
73
+ json: item,
74
+ }));
75
+ } else {
76
+ return {
77
+ json: result,
78
+ };
79
+ }
75
80
  }
76
81
  case 'getSingleUser': {
77
82
  return {
@@ -8,6 +8,7 @@ import {
8
8
  DEFAULT_API_OBJECT_LIMIT,
9
9
  } from '../../../models';
10
10
  import { fetchManyUsers } from '../../../transport';
11
+ import { WorkflowResponse } from '../../../../response';
11
12
 
12
13
  export const description = {
13
14
  name: 'Get many users',
@@ -144,7 +145,7 @@ export const properties: INodeProperties[] = [
144
145
  export async function execute(
145
146
  this: IExecuteFunctions,
146
147
  i: number
147
- ): Promise<User[]> {
148
+ ): Promise<WorkflowResponse<User[]>> {
148
149
  const active = this.getNodeParameter('active', i) as
149
150
  | boolean
150
151
  | NullOptionType;
@@ -162,5 +163,12 @@ export async function execute(
162
163
  i,
163
164
  false
164
165
  ) as boolean;
165
- return await fetchManyUsers(this, active, userType, limit, withCoworker);
166
+ const response = await fetchManyUsers(
167
+ this,
168
+ active,
169
+ userType,
170
+ limit,
171
+ withCoworker
172
+ );
173
+ return response.data;
166
174
  }
@@ -1,14 +1,11 @@
1
- import {
2
- IExecuteFunctions,
3
- INodeProperties,
4
- NodeOperationError,
5
- } from 'n8n-workflow';
6
-
1
+ import { IExecuteFunctions, INodeProperties } from 'n8n-workflow';
7
2
  import { User, ADMIN_RESOURCE } from '../../../models';
8
3
  import {
9
4
  fetchSingleUserById,
10
5
  fetchSingleUserByLimeobjectId,
11
6
  } from '../../../transport';
7
+ import { WorkflowResponse, APIResponse } from '../../../../response';
8
+ import { handleWorkflowError } from '../../../../errorHandling';
12
9
 
13
10
  export const description = {
14
11
  name: 'Get single user',
@@ -94,20 +91,22 @@ export const properties: INodeProperties[] = [
94
91
  export async function execute(
95
92
  this: IExecuteFunctions,
96
93
  i: number
97
- ): Promise<User> {
94
+ ): Promise<WorkflowResponse<User>> {
98
95
  const source = this.getNodeParameter('source', i) as string;
99
96
  const id = this.getNodeParameter('identifier', i) as string;
100
97
  const withCoworker = this.getNodeParameter('withCoworker', i) as boolean;
101
98
 
99
+ let response: APIResponse<User>;
100
+
102
101
  if (source == 'byUser') {
103
- return await fetchSingleUserById(this, id, withCoworker);
104
- }
105
- if (source == 'byLimeobject') {
106
- return await fetchSingleUserByLimeobjectId(this, id, withCoworker);
102
+ response = await fetchSingleUserById(this, id, withCoworker);
103
+ } else if (source == 'byLimeobject') {
104
+ response = await fetchSingleUserByLimeobjectId(this, id, withCoworker);
105
+ } else {
106
+ response = handleWorkflowError(this, {
107
+ message: `The source ${source} is not supported!`,
108
+ });
107
109
  }
108
110
 
109
- throw new NodeOperationError(
110
- this.getNode(),
111
- `The source "${source}" is not supported!`
112
- );
111
+ return response.data;
113
112
  }
@@ -87,21 +87,30 @@ export async function dataOperations(
87
87
  }
88
88
  case 'updateSingleObject': {
89
89
  return {
90
- json: await operations.updateSingleObject.execute.call(this, i),
90
+ ...(await operations.updateSingleObject.execute.call(this, i)),
91
91
  };
92
92
  }
93
93
  case 'deleteSingleObject': {
94
- await operations.deleteSingleObject.execute.call(this, i);
95
- return { json: {} };
94
+ const response = await operations.deleteSingleObject.execute.call(
95
+ this,
96
+ i
97
+ );
98
+ return { json: response };
96
99
  }
97
100
  case 'getManyObjects': {
98
101
  const result = await operations.getManyObjects.execute.call(
99
102
  this,
100
103
  i
101
104
  );
102
- return result.map((item) => ({
103
- json: item,
104
- }));
105
+ if (Array.isArray(result)) {
106
+ return result.map((item) => ({
107
+ json: item,
108
+ }));
109
+ } else {
110
+ return {
111
+ json: result,
112
+ };
113
+ }
105
114
  }
106
115
  case 'getSingleFile': {
107
116
  return await operations.getSingleFile.execute.call(this, i);