@tiledesk/tiledesk-server 2.19.11 → 2.19.13

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/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@
5
5
  🚀 IN PRODUCTION 🚀
6
6
  (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
7
7
 
8
+ # 2.19.13
9
+ - Added new routes and services for Data Tables management
10
+ - Updated tybot-connector to 2.1.5
11
+
12
+ # 2.19.12
13
+ - Updated messenger-connector to 0.1.30
14
+
8
15
  # 2.19.11
9
16
  - Updated payments module
10
17
 
package/app.js CHANGED
@@ -149,6 +149,7 @@ var urls = require('./routes/urls');
149
149
  var email = require('./routes/email');
150
150
  var property = require('./routes/property');
151
151
  var segment = require('./routes/segment');
152
+ var dataTable = require('./routes/dataTable');
152
153
  var webhook = require('./routes/webhook');
153
154
  var webhooks = require('./routes/webhooks');
154
155
  var roles = require('./routes/roles');
@@ -635,6 +636,8 @@ app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session:
635
636
  app.use('/:projectid/properties',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], property);
636
637
  app.use('/:projectid/segments',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], segment);
637
638
 
639
+ app.use('/:projectid/tables', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('admin', ['bot','subscription'])], dataTable);
640
+
638
641
  app.use('/:projectid/llm', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('admin', ['bot','subscription'])], llm);
639
642
  app.use('/:projectid/openai', openai);
640
643
  app.use('/:projectid/url-preview', urlPreview);
@@ -0,0 +1,64 @@
1
+ const mongoose = require('mongoose');
2
+ const Schema = mongoose.Schema;
3
+ const winston = require('../config/winston');
4
+
5
+ const TableSchema = new Schema({
6
+ id_project: {
7
+ type: String,
8
+ required: true,
9
+ index: true
10
+ },
11
+ name: {
12
+ type: String,
13
+ required: true
14
+ },
15
+ schema: {
16
+ type: Schema.Types.Mixed,
17
+ default: []
18
+ },
19
+ createdBy: {
20
+ type: String,
21
+ required: true
22
+ },
23
+ stats: {
24
+ rows: {
25
+ type: Number,
26
+ default: 0
27
+ },
28
+ sizeBytes: {
29
+ type: Number,
30
+ default: 0
31
+ }
32
+ }
33
+ }, {
34
+ timestamps: true
35
+ });
36
+
37
+ const TableRowSchema = new Schema({
38
+ id_project: {
39
+ type: String,
40
+ required: true
41
+ },
42
+ id_table: {
43
+ type: String,
44
+ required: true
45
+ },
46
+ data: {
47
+ type: Schema.Types.Mixed,
48
+ default: {}
49
+ },
50
+ }, {
51
+ timestamps: true
52
+ });
53
+
54
+ TableRowSchema.index({ id_project: 1, id_table: 1 });
55
+
56
+ const Table = mongoose.model('Table', TableSchema);
57
+ const TableRow = mongoose.model('TableRow', TableRowSchema);
58
+
59
+ if (process.env.MONGOOSE_SYNCINDEX) {
60
+ TableRow.syncIndexes();
61
+ winston.verbose('TableRow syncIndexes');
62
+ }
63
+
64
+ module.exports = { Table, TableRow };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-server",
3
3
  "description": "The Tiledesk server module",
4
- "version": "2.19.11",
4
+ "version": "2.19.13",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -44,12 +44,12 @@
44
44
  "@tiledesk/tiledesk-dialogflow-connector": "^1.8.4",
45
45
  "@tiledesk/tiledesk-json-rules-engine": "^4.0.3",
46
46
  "@tiledesk/tiledesk-kaleyra-proxy": "^0.1.7",
47
- "@tiledesk/tiledesk-messenger-connector": "^0.1.28",
47
+ "@tiledesk/tiledesk-messenger-connector": "^0.1.30",
48
48
  "@tiledesk/tiledesk-multi-worker": "^0.3.3",
49
49
  "@tiledesk/tiledesk-rasa-connector": "^1.0.10",
50
50
  "@tiledesk/tiledesk-sms-connector": "^0.1.13",
51
51
  "@tiledesk/tiledesk-telegram-connector": "^0.1.14",
52
- "@tiledesk/tiledesk-tybot-connector": "^2.1.2",
52
+ "@tiledesk/tiledesk-tybot-connector": "^2.1.5",
53
53
  "@tiledesk/tiledesk-voice-twilio-connector": "^0.3.2",
54
54
  "@tiledesk/tiledesk-vxml-connector": "^0.1.91",
55
55
  "@tiledesk/tiledesk-whatsapp-connector": "1.0.26",
@@ -0,0 +1,280 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const winston = require('../config/winston');
4
+ const dataTableService = require('../services/dataTableService');
5
+
6
+ function getRowPayload(body) {
7
+ if (body && body.data && typeof body.data === 'object' && !Array.isArray(body.data)) {
8
+ return body.data;
9
+ }
10
+ return body;
11
+ }
12
+
13
+ function isValidationError(err) {
14
+ if (!err || !err.message) return false;
15
+ const msg = err.message;
16
+ return msg.indexOf('does not exist') !== -1 ||
17
+ msg.indexOf('required') !== -1 ||
18
+ msg.indexOf('Invalid') !== -1 ||
19
+ msg.indexOf('must be') !== -1 ||
20
+ msg.indexOf('already exists') !== -1 ||
21
+ msg.indexOf('Column id') !== -1 ||
22
+ msg.indexOf('not provided') !== -1 ||
23
+ msg.indexOf('Operator') !== -1 ||
24
+ msg.indexOf('id_row or conditions') !== -1 ||
25
+ msg.indexOf('data is required') !== -1 ||
26
+ msg.indexOf('valid JSON') !== -1;
27
+ }
28
+
29
+ function handleError(res, err, action) {
30
+ if (err && err.message === 'TABLE_SIZE_LIMIT_EXCEEDED') {
31
+ return res.status(413).send({ success: false, message: 'TABLE_SIZE_LIMIT_EXCEEDED' });
32
+ }
33
+ if (isValidationError(err)) {
34
+ const status = err.message.indexOf('already exists') !== -1 ? 409 : 400;
35
+ return res.status(status).send({ success: false, message: err.message });
36
+ }
37
+ if (err.message === 'Column not found' || err.message.indexOf('Column not found:') === 0) {
38
+ return res.status(404).send({ success: false, message: err.message });
39
+ }
40
+ winston.error('DataTable ' + action + ': ', err);
41
+ return res.status(500).send({ success: false, error: 'Error ' + action });
42
+ }
43
+
44
+ // --- Tables ---
45
+
46
+ router.get('/', async function (req, res) {
47
+ try {
48
+ res.status(200).send(await dataTableService.listTables(req.projectid));
49
+ } catch (err) {
50
+ handleError(res, err, 'finding tables');
51
+ }
52
+ });
53
+
54
+ router.get('/:id', async function (req, res) {
55
+ try {
56
+ const table = await dataTableService.getTable(req.projectid, req.params.id);
57
+ if (!table) return res.status(404).send({ success: false, error: 'Table not found' });
58
+ res.status(200).send(table);
59
+ } catch (err) {
60
+ handleError(res, err, 'finding table');
61
+ }
62
+ });
63
+
64
+ router.post('/', async function (req, res) {
65
+ try {
66
+ const table = await dataTableService.createTable(
67
+ req.projectid,
68
+ req.body,
69
+ req.user.id || req.user._id
70
+ );
71
+ res.status(200).send(table);
72
+ } catch (err) {
73
+ handleError(res, err, 'creating table');
74
+ }
75
+ });
76
+
77
+ router.put('/:id', async function (req, res) {
78
+ try {
79
+ const table = await dataTableService.updateTable(req.projectid, req.params.id, req.body);
80
+ if (!table) return res.status(404).send({ success: false, error: 'Table not found' });
81
+ res.status(200).send(table);
82
+ } catch (err) {
83
+ handleError(res, err, 'updating table');
84
+ }
85
+ });
86
+
87
+ router.delete('/:id', async function (req, res) {
88
+ try {
89
+ const deleted = await dataTableService.deleteTable(req.projectid, req.params.id);
90
+ if (!deleted) return res.status(404).send({ success: false, error: 'Table not found' });
91
+ res.status(200).send({ success: true, message: 'Table deleted successfully' });
92
+ } catch (err) {
93
+ handleError(res, err, 'deleting table');
94
+ }
95
+ });
96
+
97
+ // --- Columns ---
98
+
99
+ router.post('/:id/columns', async function (req, res) {
100
+ try {
101
+ const table = await dataTableService.addColumn(req.projectid, req.params.id, req.body);
102
+ if (!table) return res.status(404).send({ success: false, error: 'Table not found' });
103
+ res.status(200).send(table);
104
+ } catch (err) {
105
+ handleError(res, err, 'adding column');
106
+ }
107
+ });
108
+
109
+ router.patch('/:id/columns/:columnId', async function (req, res) {
110
+ try {
111
+ const table = await dataTableService.renameColumn(
112
+ req.projectid,
113
+ req.params.id,
114
+ req.params.columnId,
115
+ req.body.name
116
+ );
117
+ if (!table) return res.status(404).send({ success: false, error: 'Table not found' });
118
+ res.status(200).send(table);
119
+ } catch (err) {
120
+ handleError(res, err, 'renaming column');
121
+ }
122
+ });
123
+
124
+ router.delete('/:id/columns/:columnId', async function (req, res) {
125
+ try {
126
+ const table = await dataTableService.deleteColumn(
127
+ req.projectid,
128
+ req.params.id,
129
+ req.params.columnId
130
+ );
131
+ if (!table) return res.status(404).send({ success: false, error: 'Table not found' });
132
+ res.status(200).send(table);
133
+ } catch (err) {
134
+ handleError(res, err, 'deleting column');
135
+ }
136
+ });
137
+
138
+ // --- Rows (insert / update / upsert / delete by id_row or conditions) ---
139
+
140
+ function getRowsListParams(req) {
141
+ var params = Object.assign({}, req.query);
142
+ if (req.body && typeof req.body === 'object' && !Array.isArray(req.body)) {
143
+ if (req.body.must_match !== undefined) params.must_match = req.body.must_match;
144
+ if (req.body.match !== undefined) params.match = req.body.match;
145
+ if (req.body.conditions !== undefined) params.conditions = req.body.conditions;
146
+ }
147
+ return params;
148
+ }
149
+
150
+ router.get('/:id/rows/list', async function (req, res) {
151
+
152
+ console.log("List rows")
153
+ try {
154
+ const rows = await dataTableService.listRowsWithFilter(
155
+ req.projectid,
156
+ req.params.id,
157
+ Object.assign({}, getRowsListParams(req), { sort: -1, limit: 200 })
158
+ );
159
+ if (rows === null) return res.status(404).send({ success: false, error: 'Table not found' });
160
+ res.status(200).send(rows);
161
+ } catch (err) {
162
+ handleError(res, err, 'listing rows');
163
+ }
164
+ });
165
+
166
+ router.post('/:id/row/insert', async function (req, res) {
167
+ console.log("Insert row")
168
+ try {
169
+ const row = await dataTableService.insertRowByBody(req.projectid, req.params.id, req.body);
170
+ if (!row) return res.status(404).send({ success: false, error: 'Table not found' });
171
+ res.status(200).send(row);
172
+ } catch (err) {
173
+ handleError(res, err, 'inserting row');
174
+ }
175
+ });
176
+
177
+ router.put('/:id/row/update', async function (req, res) {
178
+ try {
179
+ const row = await dataTableService.updateRowByBody(req.projectid, req.params.id, req.body);
180
+ if (row === null) return res.status(404).send({ success: false, error: 'Table not found' });
181
+ if (row === undefined) return res.status(404).send({ success: false, error: 'Row not found' });
182
+ res.status(200).send(row);
183
+ } catch (err) {
184
+ handleError(res, err, 'updating row');
185
+ }
186
+ });
187
+
188
+ router.put('/:id/row/upsert', async function (req, res) {
189
+ try {
190
+ const result = await dataTableService.upsertRowByBody(req.projectid, req.params.id, req.body);
191
+ if (result === null) return res.status(404).send({ success: false, error: 'Table not found' });
192
+ res.status(200).send(result);
193
+ } catch (err) {
194
+ if (err.message === 'Multiple rows match the conditions') {
195
+ return res.status(409).send({ success: false, message: err.message });
196
+ }
197
+ handleError(res, err, 'upserting row');
198
+ }
199
+ });
200
+
201
+ router.put('/:id/row/delete', async function (req, res) {
202
+ try {
203
+ const row = await dataTableService.deleteRowByBody(req.projectid, req.params.id, req.body);
204
+ if (row === null) return res.status(404).send({ success: false, error: 'Table not found' });
205
+ if (row === undefined) return res.status(404).send({ success: false, error: 'Row not found' });
206
+ res.status(200).send(row);
207
+ } catch (err) {
208
+ handleError(res, err, 'deleting row');
209
+ }
210
+ });
211
+
212
+ // --- Rows (REST) ---
213
+
214
+ // router.get('/:id/rows', async function (req, res) {
215
+ // try {
216
+ // const rows = await dataTableService.listRows(req.projectid, req.params.id);
217
+ // if (rows === null) return res.status(404).send({ success: false, error: 'Table not found' });
218
+ // res.status(200).send(rows);
219
+ // } catch (err) {
220
+ // handleError(res, err, 'finding rows');
221
+ // }
222
+ // });
223
+
224
+ // router.get('/:id/rows/:rowId', async function (req, res) {
225
+ // try {
226
+ // const row = await dataTableService.getRow(req.projectid, req.params.id, req.params.rowId);
227
+ // if (!row) return res.status(404).send({ success: false, error: 'Row not found' });
228
+ // res.status(200).send(row);
229
+ // } catch (err) {
230
+ // handleError(res, err, 'finding row');
231
+ // }
232
+ // });
233
+
234
+ // router.post('/:id/rows', async function (req, res) {
235
+ // try {
236
+ // const row = await dataTableService.insertRow(req.projectid, req.params.id, getRowPayload(req.body));
237
+ // if (!row) return res.status(404).send({ success: false, error: 'Table not found' });
238
+ // res.status(200).send(row);
239
+ // } catch (err) {
240
+ // handleError(res, err, 'inserting row');
241
+ // }
242
+ // });
243
+
244
+ // router.put('/:id/rows/:rowId', async function (req, res) {
245
+ // try {
246
+ // const row = await dataTableService.updateRow(
247
+ // req.projectid,
248
+ // req.params.id,
249
+ // req.params.rowId,
250
+ // getRowPayload(req.body)
251
+ // );
252
+ // if (row === null) return res.status(404).send({ success: false, error: 'Table not found' });
253
+ // if (row === undefined) return res.status(404).send({ success: false, error: 'Row not found' });
254
+ // res.status(200).send(row);
255
+ // } catch (err) {
256
+ // handleError(res, err, 'updating row');
257
+ // }
258
+ // });
259
+
260
+ // router.delete('/:id/rows/:rowId', async function (req, res) {
261
+ // try {
262
+ // const row = await dataTableService.deleteRow(req.projectid, req.params.id, req.params.rowId);
263
+ // if (!row) return res.status(404).send({ success: false, error: 'Row not found' });
264
+ // res.status(200).send(row);
265
+ // } catch (err) {
266
+ // handleError(res, err, 'deleting row');
267
+ // }
268
+ // });
269
+
270
+ // router.post('/:id/rows/search', async function (req, res) {
271
+ // try {
272
+ // const rows = await dataTableService.searchRows(req.projectid, req.params.id, req.body);
273
+ // if (rows === null) return res.status(404).send({ success: false, error: 'Table not found' });
274
+ // res.status(200).send(rows);
275
+ // } catch (err) {
276
+ // handleError(res, err, 'searching rows');
277
+ // }
278
+ // });
279
+
280
+ module.exports = router;