@worktables/n8n-nodes-worktables 12.0.7 → 12.1.1

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.
@@ -208,6 +208,12 @@ class Worktables {
208
208
  value: 'updateItem',
209
209
  action: 'Update column values of an item',
210
210
  },
211
+ {
212
+ name: 'Create or Update Item',
213
+ value: 'createOrUpdateItem',
214
+ description: 'Create a new item or update existing one based on item ID',
215
+ action: 'Create or update an item',
216
+ },
211
217
  {
212
218
  name: 'Delete an Item',
213
219
  value: 'deleteItem',
@@ -250,7 +256,7 @@ class Worktables {
250
256
  action: 'Upload files to column',
251
257
  },
252
258
  ],
253
- default: 'createItem',
259
+ default: 'createOrUpdateItem',
254
260
  required: true,
255
261
  displayOptions: {
256
262
  show: { resource: ['item'] },
@@ -599,6 +605,7 @@ class Worktables {
599
605
  'createSubitem',
600
606
  'createItem',
601
607
  'updateItem',
608
+ 'createOrUpdateItem',
602
609
  'listBoardGroups',
603
610
  'createGroup',
604
611
  'duplicateGroup',
@@ -978,6 +985,18 @@ class Worktables {
978
985
  },
979
986
  },
980
987
  },
988
+ {
989
+ displayName: 'Item ID (Optional)',
990
+ name: 'itemIdOptional',
991
+ type: 'string',
992
+ default: '',
993
+ description: 'Item ID to update. If left empty, a new item will be created. If provided, the existing item will be updated.',
994
+ displayOptions: {
995
+ show: {
996
+ operation: ['createOrUpdateItem'],
997
+ },
998
+ },
999
+ },
981
1000
  {
982
1001
  displayName: 'Item',
983
1002
  name: 'itemId',
@@ -1096,7 +1115,7 @@ class Worktables {
1096
1115
  displayOptions: {
1097
1116
  show: {
1098
1117
  resource: ['item', 'subitem'],
1099
- operation: ['createItem', 'createSubitem'],
1118
+ operation: ['createItem', 'createSubitem', 'createOrUpdateItem'],
1100
1119
  },
1101
1120
  },
1102
1121
  },
@@ -1109,7 +1128,7 @@ class Worktables {
1109
1128
  displayOptions: {
1110
1129
  show: {
1111
1130
  resource: ['item'],
1112
- operation: ['createItem'],
1131
+ operation: ['createItem', 'createOrUpdateItem'],
1113
1132
  },
1114
1133
  },
1115
1134
  },
@@ -1124,7 +1143,7 @@ class Worktables {
1124
1143
  displayOptions: {
1125
1144
  show: {
1126
1145
  resource: ['item'],
1127
- operation: ['createItem'],
1146
+ operation: ['createItem', 'createOrUpdateItem'],
1128
1147
  isSubitem: [true],
1129
1148
  },
1130
1149
  },
@@ -1143,7 +1162,7 @@ class Worktables {
1143
1162
  displayOptions: {
1144
1163
  show: {
1145
1164
  resource: ['item', 'subitem'],
1146
- operation: ['createItem', 'updateItem', 'createSubitem'],
1165
+ operation: ['createItem', 'updateItem', 'createSubitem', 'createOrUpdateItem'],
1147
1166
  },
1148
1167
  },
1149
1168
  options: [
@@ -2516,7 +2535,7 @@ class Worktables {
2516
2535
  };
2517
2536
  }
2518
2537
  async execute() {
2519
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10;
2538
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11;
2520
2539
  const resource = this.getNodeParameter('resource', 0);
2521
2540
  const operation = this.getNodeParameter('operation', 0);
2522
2541
  const credentials = await this.getCredentials('WorktablesApi');
@@ -3882,6 +3901,240 @@ class Worktables {
3882
3901
  case 'updateColumnValues': {
3883
3902
  break;
3884
3903
  }
3904
+ case 'createOrUpdateItem': {
3905
+ const itemName = this.getNodeParameter('itemName', 0);
3906
+ const boardId = this.getNodeParameter('boardId', 0);
3907
+ const isSubitem = this.getNodeParameter('isSubitem', 0);
3908
+ const itemIdOptional = this.getNodeParameter('itemIdOptional', 0, false);
3909
+ const raw = this.getNodeParameter('columnValues', 0);
3910
+ const columnValues = raw.column;
3911
+ let column_values_object = {};
3912
+ console.log('Column Values:', JSON.stringify(raw, null, 2));
3913
+ if ((columnValues === null || columnValues === void 0 ? void 0 : columnValues.length) > 0) {
3914
+ const columnTypeResponse = await this.helpers.request({
3915
+ method: 'POST',
3916
+ url: 'https://api.monday.com/v2',
3917
+ headers: {
3918
+ Authorization: `Bearer ${apiKey}`,
3919
+ 'Content-Type': 'application/json',
3920
+ },
3921
+ body: {
3922
+ query: `query {
3923
+ boards(ids: ${boardId}) {
3924
+ columns {
3925
+ id
3926
+ type
3927
+ }
3928
+ }
3929
+ }`,
3930
+ },
3931
+ });
3932
+ const columnsType = JSON.parse(columnTypeResponse).data.boards[0].columns;
3933
+ for (const col of columnValues) {
3934
+ const columnId = col.columnId;
3935
+ const columnDef = columnsType.find((c) => c.id === columnId);
3936
+ const type = columnDef === null || columnDef === void 0 ? void 0 : columnDef.type;
3937
+ if (!type || type === 'text' || type === 'simple' || col.columnType === 'simple') {
3938
+ console.log('Processing text/simple column:', col);
3939
+ if (col.columnValue !== undefined) {
3940
+ const value = col.columnValue;
3941
+ if (typeof value === 'string' && type === 'file') {
3942
+ const links = value.split(',').map((item) => {
3943
+ const [link, ...nameParts] = item.trim().split(/\s+/);
3944
+ return {
3945
+ fileType: 'LINK',
3946
+ linkToFile: link,
3947
+ name: nameParts.join(' '),
3948
+ };
3949
+ });
3950
+ column_values_object[columnId] = { files: links };
3951
+ }
3952
+ else if (typeof value === 'string') {
3953
+ column_values_object[columnId] = value.replace(/\n/g, '\\n');
3954
+ }
3955
+ else {
3956
+ column_values_object[columnId] = value;
3957
+ }
3958
+ }
3959
+ continue;
3960
+ }
3961
+ else if (col.columnType === 'objectValue') {
3962
+ console.log('Processing objectValue for column:', columnId);
3963
+ try {
3964
+ const parsedValue = JSON.parse(col.objectValue || '{}');
3965
+ column_values_object[columnId] = parsedValue;
3966
+ }
3967
+ catch (error) {
3968
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), {
3969
+ message: `Invalid JSON format for column ${columnId}: ${error.message}`,
3970
+ });
3971
+ }
3972
+ continue;
3973
+ }
3974
+ switch (type) {
3975
+ case 'checkbox':
3976
+ column_values_object[columnId] = col.checkboxValue ? { checked: 'true' } : { checked: 'false' };
3977
+ break;
3978
+ case 'status':
3979
+ column_values_object[columnId] = { label: col.statusLabel || 'Working on it' };
3980
+ break;
3981
+ case 'location':
3982
+ column_values_object[columnId] = {
3983
+ lat: col.latitude || '0',
3984
+ lng: col.longitude || '0',
3985
+ address: col.address || '',
3986
+ };
3987
+ break;
3988
+ case 'dropdown':
3989
+ column_values_object[columnId] = { label: col.dropdownValue || '' };
3990
+ break;
3991
+ case 'people':
3992
+ if (col.peopleValue) {
3993
+ const peopleIds = Array.isArray(col.peopleValue) ? col.peopleValue : [col.peopleValue];
3994
+ column_values_object[columnId] = { personsAndTeams: peopleIds.map(id => ({ id, kind: 'person' })) };
3995
+ }
3996
+ break;
3997
+ case 'team':
3998
+ if (col.teamsValue) {
3999
+ const teamIds = Array.isArray(col.teamsValue) ? col.teamsValue : [col.teamsValue];
4000
+ column_values_object[columnId] = { personsAndTeams: teamIds.map(id => ({ id, kind: 'team' })) };
4001
+ }
4002
+ break;
4003
+ case 'timeline':
4004
+ column_values_object[columnId] = {
4005
+ from: col.startDate || '',
4006
+ to: col.endDate || '',
4007
+ };
4008
+ break;
4009
+ case 'date':
4010
+ column_values_object[columnId] = { date: col.dateValue || '' };
4011
+ break;
4012
+ case 'email':
4013
+ column_values_object[columnId] = {
4014
+ email: col.emailValue || '',
4015
+ text: col.emailText || '',
4016
+ };
4017
+ break;
4018
+ case 'link':
4019
+ column_values_object[columnId] = {
4020
+ url: col.url || '',
4021
+ text: col.linkText || '',
4022
+ };
4023
+ break;
4024
+ case 'phone':
4025
+ column_values_object[columnId] = {
4026
+ phone: col.phoneValue || '',
4027
+ countryShortName: col.countryCode || 'US',
4028
+ };
4029
+ break;
4030
+ case 'file':
4031
+ if ((_v = col.fileLinks) === null || _v === void 0 ? void 0 : _v.file) {
4032
+ column_values_object[columnId] = { files: col.fileLinks.file };
4033
+ }
4034
+ break;
4035
+ default:
4036
+ if (col.columnValue !== undefined) {
4037
+ column_values_object[columnId] = col.columnValue;
4038
+ }
4039
+ }
4040
+ }
4041
+ }
4042
+ let mutation;
4043
+ let formatted;
4044
+ if (itemIdOptional && itemIdOptional.trim() !== '') {
4045
+ console.log('Updating existing item:', itemIdOptional);
4046
+ mutation = `mutation {
4047
+ change_multiple_column_values(
4048
+ create_labels_if_missing: true,
4049
+ board_id: ${boardId},
4050
+ item_id: "${itemIdOptional}",
4051
+ column_values: "${JSON.stringify(column_values_object)
4052
+ .replace(/"/g, '\\"')
4053
+ .replace(/(^|[^\\])\\n/g, '$1\\\\n')}"
4054
+ ) {
4055
+ id
4056
+ url
4057
+ board {
4058
+ id
4059
+ }
4060
+ }
4061
+ }`;
4062
+ console.log('Generated Update Mutation:', mutation);
4063
+ response = await this.helpers.request({
4064
+ method: 'POST',
4065
+ url: 'https://api.monday.com/v2',
4066
+ headers,
4067
+ body: { query: mutation },
4068
+ });
4069
+ const responseData = JSON.parse(response);
4070
+ const itemData = responseData.data.change_multiple_column_values;
4071
+ formatted = {
4072
+ id: itemData.id,
4073
+ url: itemData.url,
4074
+ operation: 'update',
4075
+ board_id: itemData.board.id,
4076
+ column_values: column_values_object,
4077
+ };
4078
+ }
4079
+ else {
4080
+ console.log('Creating new item:', itemName);
4081
+ const parentId = this.getNodeParameter('parentId', 0, false);
4082
+ if (isSubitem && parentId) {
4083
+ mutation = `mutation {
4084
+ create_subitem(
4085
+ parent_item_id: ${parentId},
4086
+ item_name: "${itemName}",
4087
+ column_values: "${JSON.stringify(column_values_object).replace(/"/g, '\\"').replace(/(^|[^\\])\\n/g, '$1\\\\n')}"
4088
+ ) {
4089
+ id
4090
+ name
4091
+ url
4092
+ board {
4093
+ id
4094
+ }
4095
+ }
4096
+ }`;
4097
+ }
4098
+ else {
4099
+ mutation = `mutation {
4100
+ create_item(
4101
+ board_id: ${boardId},
4102
+ item_name: "${itemName}",
4103
+ column_values: "${JSON.stringify(column_values_object).replace(/"/g, '\\"').replace(/(^|[^\\])\\n/g, '$1\\\\n')}"
4104
+ ) {
4105
+ id
4106
+ name
4107
+ url
4108
+ board {
4109
+ id
4110
+ }
4111
+ }
4112
+ }`;
4113
+ }
4114
+ response = await this.helpers.request({
4115
+ method: 'POST',
4116
+ url: 'https://api.monday.com/v2',
4117
+ headers,
4118
+ body: { query: mutation },
4119
+ });
4120
+ const responseData = JSON.parse(response);
4121
+ const itemData = isSubitem && parentId
4122
+ ? responseData.data.create_subitem
4123
+ : responseData.data.create_item;
4124
+ formatted = {
4125
+ id: itemData.id,
4126
+ name: itemData.name,
4127
+ url: itemData.url,
4128
+ operation: 'create',
4129
+ board_id: itemData.board.id,
4130
+ column_values: column_values_object,
4131
+ };
4132
+ if (isSubitem && parentId) {
4133
+ formatted.parent_item = { id: parentId };
4134
+ }
4135
+ }
4136
+ return [[{ json: formatted }]];
4137
+ }
3885
4138
  case 'deleteItem': {
3886
4139
  console.log('Delete an item');
3887
4140
  const itemId = this.getNodeParameter('itemId', 0);
@@ -3995,7 +4248,7 @@ class Worktables {
3995
4248
  const sortOptions = this.getNodeParameter('sortOptions', 0, { sortBy: [] });
3996
4249
  const logicalOperator = this.getNodeParameter('logicalOperator', 0);
3997
4250
  let rulesArray = [];
3998
- if (((_v = filterRules === null || filterRules === void 0 ? void 0 : filterRules.rule) === null || _v === void 0 ? void 0 : _v.length) > 0) {
4251
+ if (((_w = filterRules === null || filterRules === void 0 ? void 0 : filterRules.rule) === null || _w === void 0 ? void 0 : _w.length) > 0) {
3999
4252
  rulesArray = filterRules.rule.map((rule) => {
4000
4253
  let formattedValue;
4001
4254
  if (['is_empty', 'is_not_empty'].includes(rule.operator)) {
@@ -4039,7 +4292,7 @@ class Worktables {
4039
4292
  });
4040
4293
  }
4041
4294
  const orderByArray = [];
4042
- if (((_w = sortOptions === null || sortOptions === void 0 ? void 0 : sortOptions.sortBy) === null || _w === void 0 ? void 0 : _w.length) > 0) {
4295
+ if (((_x = sortOptions === null || sortOptions === void 0 ? void 0 : sortOptions.sortBy) === null || _x === void 0 ? void 0 : _x.length) > 0) {
4043
4296
  sortOptions.sortBy.forEach((sort) => {
4044
4297
  orderByArray.push(`{
4045
4298
  column_id: "${sort.columnId}",
@@ -4085,7 +4338,7 @@ class Worktables {
4085
4338
  body: { query },
4086
4339
  });
4087
4340
  const parsed = JSON.parse(rawResponse);
4088
- const items = ((_0 = (_z = (_y = (_x = parsed === null || parsed === void 0 ? void 0 : parsed.data) === null || _x === void 0 ? void 0 : _x.boards) === null || _y === void 0 ? void 0 : _y[0]) === null || _z === void 0 ? void 0 : _z.items_page) === null || _0 === void 0 ? void 0 : _0.items) || [];
4341
+ const items = ((_1 = (_0 = (_z = (_y = parsed === null || parsed === void 0 ? void 0 : parsed.data) === null || _y === void 0 ? void 0 : _y.boards) === null || _z === void 0 ? void 0 : _z[0]) === null || _0 === void 0 ? void 0 : _0.items_page) === null || _1 === void 0 ? void 0 : _1.items) || [];
4089
4342
  const formattedItems = await Promise.all(items.map(async (item) => {
4090
4343
  const formatted = {
4091
4344
  id: item.id,
@@ -4223,7 +4476,7 @@ class Worktables {
4223
4476
  body: { query },
4224
4477
  });
4225
4478
  const parsed = JSON.parse(rawResponse);
4226
- const items = ((_6 = (_5 = (_4 = (_3 = (_2 = (_1 = parsed === null || parsed === void 0 ? void 0 : parsed.data) === null || _1 === void 0 ? void 0 : _1.boards) === null || _2 === void 0 ? void 0 : _2[0]) === null || _3 === void 0 ? void 0 : _3.groups) === null || _4 === void 0 ? void 0 : _4[0]) === null || _5 === void 0 ? void 0 : _5.items_page) === null || _6 === void 0 ? void 0 : _6.items) || [];
4479
+ const items = ((_7 = (_6 = (_5 = (_4 = (_3 = (_2 = parsed === null || parsed === void 0 ? void 0 : parsed.data) === null || _2 === void 0 ? void 0 : _2.boards) === null || _3 === void 0 ? void 0 : _3[0]) === null || _4 === void 0 ? void 0 : _4.groups) === null || _5 === void 0 ? void 0 : _5[0]) === null || _6 === void 0 ? void 0 : _6.items_page) === null || _7 === void 0 ? void 0 : _7.items) || [];
4227
4480
  const formattedItems = await Promise.all(items.map(async (item) => {
4228
4481
  const formatted = {
4229
4482
  id: item.id,
@@ -4347,7 +4600,7 @@ class Worktables {
4347
4600
  body: { query: mutation },
4348
4601
  });
4349
4602
  console.log('Create Update Result:', JSON.stringify(response, null, 2));
4350
- const updateId = (_8 = (_7 = JSON.parse(response).data) === null || _7 === void 0 ? void 0 : _7.create_update) === null || _8 === void 0 ? void 0 : _8.id;
4603
+ const updateId = (_9 = (_8 = JSON.parse(response).data) === null || _8 === void 0 ? void 0 : _8.create_update) === null || _9 === void 0 ? void 0 : _9.id;
4351
4604
  if (!updateId) {
4352
4605
  throw new n8n_workflow_1.NodeApiError(this.getNode(), {
4353
4606
  message: 'Error creating update: Update not created, no ID returned',
@@ -4667,7 +4920,7 @@ class Worktables {
4667
4920
  body: { query },
4668
4921
  json: true,
4669
4922
  });
4670
- const asset = (_10 = (_9 = responseFile === null || responseFile === void 0 ? void 0 : responseFile.data) === null || _9 === void 0 ? void 0 : _9.assets) === null || _10 === void 0 ? void 0 : _10[0];
4923
+ const asset = (_11 = (_10 = responseFile === null || responseFile === void 0 ? void 0 : responseFile.data) === null || _10 === void 0 ? void 0 : _10.assets) === null || _11 === void 0 ? void 0 : _11[0];
4671
4924
  if (!(asset === null || asset === void 0 ? void 0 : asset.public_url)) {
4672
4925
  throw new n8n_workflow_1.NodeApiError(this.getNode(), {
4673
4926
  message: 'Public URL not found for the given file ID.',