@budibase/server 1.2.44-alpha.0 → 1.2.46

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 (205) hide show
  1. package/__mocks__/mongodb.ts +0 -4
  2. package/__mocks__/node-fetch.ts +1 -8
  3. package/builder/assets/index.08dd0c5e.css +6 -0
  4. package/builder/assets/index.f6823431.js +975 -0
  5. package/builder/assets/{vendor.67dbd8fa.js → vendor.6bcafa60.js} +1 -1
  6. package/builder/index.html +3 -3
  7. package/coverage/clover.xml +714 -727
  8. package/coverage/coverage-final.json +27 -27
  9. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/index.html +1 -1
  18. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  24. package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  28. package/coverage/lcov-report/api/controllers/row/index.html +35 -35
  29. package/coverage/lcov-report/api/controllers/row/internal.js.html +88 -46
  30. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +191 -317
  31. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +15 -15
  32. package/coverage/lcov-report/api/controllers/row/utils.js.html +30 -39
  33. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  34. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +41 -41
  36. package/coverage/lcov-report/api/controllers/table/external.js.html +2 -2
  37. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  38. package/coverage/lcov-report/api/controllers/table/index.js.html +17 -17
  39. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/user.js.html +19 -19
  41. package/coverage/lcov-report/api/controllers/view/exporters.js.html +2 -2
  42. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  43. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  44. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  45. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  46. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  47. package/coverage/lcov-report/api/index.html +1 -1
  48. package/coverage/lcov-report/api/index.js.html +5 -5
  49. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/index.html +1 -1
  60. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/utils/index.html +1 -1
  74. package/coverage/lcov-report/api/routes/utils/validators.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  77. package/coverage/lcov-report/automations/actions.js.html +1 -1
  78. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  79. package/coverage/lcov-report/automations/bullboard.js.html +13 -7
  80. package/coverage/lcov-report/automations/index.html +12 -12
  81. package/coverage/lcov-report/automations/index.js.html +1 -1
  82. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  83. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  84. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  87. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/index.html +1 -1
  89. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  100. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  101. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  102. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  108. package/coverage/lcov-report/constants/index.html +1 -1
  109. package/coverage/lcov-report/constants/index.js.html +30 -30
  110. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  111. package/coverage/lcov-report/constants/screens.js.html +1 -1
  112. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  113. package/coverage/lcov-report/db/index.html +1 -1
  114. package/coverage/lcov-report/db/index.js.html +1 -1
  115. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +11 -11
  116. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  117. package/coverage/lcov-report/db/linkedRows/index.js.html +19 -19
  118. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +7 -7
  119. package/coverage/lcov-report/db/newid.js.html +4 -4
  120. package/coverage/lcov-report/db/utils.js.html +71 -71
  121. package/coverage/lcov-report/events/AutomationEmitter.js.html +5 -5
  122. package/coverage/lcov-report/events/index.html +1 -1
  123. package/coverage/lcov-report/events/index.js.html +1 -1
  124. package/coverage/lcov-report/events/utils.js.html +1 -1
  125. package/coverage/lcov-report/index.html +25 -25
  126. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  127. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  128. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  129. package/coverage/lcov-report/middleware/builder.js.html +12 -12
  130. package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
  131. package/coverage/lcov-report/middleware/index.html +1 -1
  132. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  133. package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
  134. package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
  135. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  136. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  137. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  138. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  139. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  140. package/coverage/lcov-report/utilities/global.js.html +31 -31
  141. package/coverage/lcov-report/utilities/index.html +1 -1
  142. package/coverage/lcov-report/utilities/index.js.html +23 -23
  143. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
  144. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  145. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  146. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  147. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  148. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +39 -39
  149. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +10 -10
  150. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  151. package/coverage/lcov-report/utilities/security.js.html +1 -1
  152. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  153. package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
  154. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
  155. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  156. package/coverage/lcov-report/utilities/users.js.html +7 -7
  157. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  158. package/coverage/lcov.info +1168 -1194
  159. package/dist/api/controllers/row/internal.js +15 -1
  160. package/dist/api/controllers/row/internalSearch.js +4 -39
  161. package/dist/api/controllers/row/utils.js +1 -3
  162. package/dist/api/controllers/static/index.js +2 -8
  163. package/dist/api/controllers/table/external.js +1 -1
  164. package/dist/api/routes/static.js +0 -2
  165. package/dist/automations/bullboard.js +2 -0
  166. package/dist/automations/listeners.js +102 -0
  167. package/dist/automations/logging/index.js +0 -3
  168. package/dist/automations/utils.js +6 -2
  169. package/dist/integrations/base/sql.js +30 -62
  170. package/dist/integrations/base/utils.js +27 -13
  171. package/dist/integrations/microsoftSqlServer.js +2 -5
  172. package/dist/integrations/mongodb.js +8 -35
  173. package/dist/integrations/mysql.js +2 -2
  174. package/dist/integrations/postgres.js +2 -5
  175. package/dist/package.json +7 -7
  176. package/dist/threads/automation.js +27 -11
  177. package/dist/tsconfig.build.tsbuildinfo +1 -1
  178. package/dist/utilities/fileSystem/index.js +1 -2
  179. package/package.json +8 -8
  180. package/src/api/controllers/row/internal.js +15 -1
  181. package/src/api/controllers/row/internalSearch.js +3 -45
  182. package/src/api/controllers/row/utils.js +1 -4
  183. package/src/api/controllers/static/index.ts +1 -5
  184. package/src/api/controllers/table/external.js +1 -1
  185. package/src/api/routes/static.ts +0 -11
  186. package/src/api/routes/tests/row.spec.js +149 -67
  187. package/src/automations/bullboard.js +2 -0
  188. package/src/automations/listeners.ts +78 -0
  189. package/src/automations/logging/index.ts +0 -3
  190. package/src/automations/utils.ts +7 -6
  191. package/src/integrations/base/sql.ts +30 -67
  192. package/src/integrations/base/utils.ts +18 -9
  193. package/src/integrations/microsoftSqlServer.ts +2 -3
  194. package/src/integrations/mongodb.ts +8 -35
  195. package/src/integrations/mysql.ts +1 -1
  196. package/src/integrations/postgres.ts +1 -2
  197. package/src/integrations/tests/mongo.spec.js +0 -218
  198. package/src/integrations/tests/sql.spec.js +11 -101
  199. package/src/threads/automation.ts +35 -16
  200. package/src/utilities/fileSystem/index.js +0 -2
  201. package/builder/assets/index.6b1c808b.css +0 -6
  202. package/builder/assets/index.7e1eb5c8.js +0 -977
  203. package/dist/integrations/base/query.js +0 -27
  204. package/src/api/routes/tests/internalSearch.spec.js +0 -176
  205. package/src/integrations/base/query.ts +0 -16
@@ -346,11 +346,25 @@ exports.exportRows = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
346
346
  const table = yield db.get(ctx.params.tableId);
347
347
  const rowIds = ctx.request.body.rows;
348
348
  let format = ctx.query.format;
349
+ const { columns } = ctx.request.body;
349
350
  let response = (yield db.allDocs({
350
351
  include_docs: true,
351
352
  keys: rowIds,
352
353
  })).rows.map(row => row.doc);
353
- let rows = yield outputProcessing(table, response);
354
+ let result = yield outputProcessing(table, response);
355
+ let rows = [];
356
+ // Filter data to only specified columns if required
357
+ if (columns && columns.length) {
358
+ for (let i = 0; i < result.length; i++) {
359
+ rows[i] = {};
360
+ for (let column of columns) {
361
+ rows[i][column] = result[i][column];
362
+ }
363
+ }
364
+ }
365
+ else {
366
+ rows = result;
367
+ }
354
368
  let headers = Object.keys(rows[0]);
355
369
  const exporter = exporters[format];
356
370
  const filename = `export.${format}`;
@@ -9,7 +9,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  const { SearchIndexes } = require("../../../db/utils");
12
- const { removeKeyNumbering } = require("./utils");
13
12
  const fetch = require("node-fetch");
14
13
  const { getCouchInfo } = require("@budibase/backend-core/db");
15
14
  const { getAppId } = require("@budibase/backend-core/context");
@@ -19,7 +18,7 @@ const { getAppId } = require("@budibase/backend-core/context");
19
18
  */
20
19
  class QueryBuilder {
21
20
  constructor(base) {
22
- this.query = Object.assign({ allOr: false, string: {}, fuzzy: {}, range: {}, equal: {}, notEqual: {}, empty: {}, notEmpty: {}, oneOf: {}, contains: {}, notContains: {}, containsAny: {} }, base);
21
+ this.query = Object.assign({ allOr: false, string: {}, fuzzy: {}, range: {}, equal: {}, notEqual: {}, empty: {}, notEmpty: {}, oneOf: {}, contains: {} }, base);
23
22
  this.limit = 50;
24
23
  this.sortOrder = "ascending";
25
24
  this.sortType = "string";
@@ -105,14 +104,6 @@ class QueryBuilder {
105
104
  this.query.contains[key] = value;
106
105
  return this;
107
106
  }
108
- addNotContains(key, value) {
109
- this.query.notContains[key] = value;
110
- return this;
111
- }
112
- addContainsAny(key, value) {
113
- this.query.containsAny[key] = value;
114
- return this;
115
- }
116
107
  /**
117
108
  * Preprocesses a value before going into a lucene search.
118
109
  * Transforms strings to lowercase and wraps strings and bools in quotes.
@@ -155,27 +146,11 @@ class QueryBuilder {
155
146
  }
156
147
  return `${key}:${builder.preprocess(value, allPreProcessingOpts)}`;
157
148
  };
158
- const contains = (key, value, mode = "AND") => {
159
- if (Array.isArray(value) && value.length === 0) {
149
+ const contains = (key, value) => {
150
+ if (!value && value !== 0) {
160
151
  return null;
161
152
  }
162
- if (!Array.isArray(value)) {
163
- return `${key}:${value}`;
164
- }
165
- let statement = `${builder.preprocess(value[0], { escape: true })}`;
166
- for (let i = 1; i < value.length; i++) {
167
- statement += ` ${mode} ${builder.preprocess(value[i], {
168
- escape: true,
169
- })}`;
170
- }
171
- return `${key}:(${statement})`;
172
- };
173
- const notContains = (key, value) => {
174
- const allPrefix = allOr === "" ? "*:* AND" : "";
175
- return allPrefix + "NOT " + contains(key, value);
176
- };
177
- const containsAny = (key, value) => {
178
- return contains(key, value, "OR");
153
+ return `${key}:${builder.preprocess(value, { escape: true })}`;
179
154
  };
180
155
  const oneOf = (key, value) => {
181
156
  if (!Array.isArray(value)) {
@@ -194,8 +169,6 @@ class QueryBuilder {
194
169
  };
195
170
  function build(structure, queryFn) {
196
171
  for (let [key, value] of Object.entries(structure)) {
197
- // check for new format - remove numbering if needed
198
- key = removeKeyNumbering(key);
199
172
  key = builder.preprocess(key.replace(/ /g, "_"), {
200
173
  escape: true,
201
174
  });
@@ -273,12 +246,6 @@ class QueryBuilder {
273
246
  if (this.query.contains) {
274
247
  build(this.query.contains, contains);
275
248
  }
276
- if (this.query.notContains) {
277
- build(this.query.notContains, notContains);
278
- }
279
- if (this.query.containsAny) {
280
- build(this.query.containsAny, containsAny);
281
- }
282
249
  // make sure table ID is always added as an AND
283
250
  if (tableId) {
284
251
  query = `(${query})`;
@@ -313,8 +280,6 @@ class QueryBuilder {
313
280
  });
314
281
  }
315
282
  }
316
- // exported for unit testing
317
- exports.QueryBuilder = QueryBuilder;
318
283
  /**
319
284
  * Executes a lucene search query.
320
285
  * @param url The query URL
@@ -13,9 +13,8 @@ const { cloneDeep } = require("lodash/fp");
13
13
  const { InternalTables } = require("../../../db/utils");
14
14
  const userController = require("../user");
15
15
  const { FieldTypes } = require("../../../constants");
16
+ const { makeExternalQuery } = require("../../../integrations/base/utils");
16
17
  const { getAppDB } = require("@budibase/backend-core/context");
17
- const { makeExternalQuery } = require("../../../integrations/base/query");
18
- const { removeKeyNumbering } = require("../../../integrations/base/utils");
19
18
  validateJs.extend(validateJs.validators.datetime, {
20
19
  parse: function (value) {
21
20
  return new Date(value).getTime();
@@ -25,7 +24,6 @@ validateJs.extend(validateJs.validators.datetime, {
25
24
  return new Date(value).toISOString();
26
25
  },
27
26
  });
28
- exports.removeKeyNumbering = removeKeyNumbering;
29
27
  exports.getDatasourceAndQuery = (json) => __awaiter(void 0, void 0, void 0, function* () {
30
28
  const datasourceId = json.endpoint.datasourceId;
31
29
  const db = getAppDB();
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.getSignedUploadURL = exports.serveClientLibrary = exports.serveApp = exports.deleteObjects = exports.uploadFile = exports.serveBuilder = exports.toggleBetaUiFeature = void 0;
12
+ exports.getSignedUploadURL = exports.serveClientLibrary = exports.serveApp = exports.uploadFile = exports.serveBuilder = exports.toggleBetaUiFeature = void 0;
13
13
  require("svelte/register");
14
14
  const send = require("koa-send");
15
15
  const { resolve, join } = require("../../../utilities/centralPath");
@@ -19,7 +19,7 @@ const { processString } = require("@budibase/string-templates");
19
19
  const { loadHandlebarsFile, NODE_MODULES_PATH, TOP_LEVEL_PATH, } = require("../../../utilities/fileSystem");
20
20
  const env = require("../../../environment");
21
21
  const { clientLibraryPath } = require("../../../utilities");
22
- const { upload, deleteFiles } = require("../../../utilities/fileSystem");
22
+ const { upload } = require("../../../utilities/fileSystem");
23
23
  const { attachmentsRelativeURL } = require("../../../utilities");
24
24
  const { DocumentType } = require("../../../db/utils");
25
25
  const { getAppDB, getAppId } = require("@budibase/backend-core/context");
@@ -95,12 +95,6 @@ const uploadFile = function (ctx) {
95
95
  });
96
96
  };
97
97
  exports.uploadFile = uploadFile;
98
- const deleteObjects = function (ctx) {
99
- return __awaiter(this, void 0, void 0, function* () {
100
- ctx.body = yield deleteFiles(ObjectStoreBuckets.APPS, ctx.request.body.keys);
101
- });
102
- };
103
- exports.deleteObjects = deleteObjects;
104
98
  const serveApp = function (ctx) {
105
99
  return __awaiter(this, void 0, void 0, function* () {
106
100
  const db = getAppDB({ skip_setup: true });
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  const { buildExternalTableId, breakExternalTableId, } = require("../../../integrations/utils");
12
12
  const { getTable, generateForeignKey, generateJunctionTableName, foreignKeyStructure, hasTypeChanged, } = require("./utils");
13
13
  const { DataSourceOperation, FieldTypes, RelationshipTypes, } = require("../../../constants");
14
- const { makeExternalQuery } = require("../../../integrations/base/query");
14
+ const { makeExternalQuery } = require("../../../integrations/base/utils");
15
15
  const { cloneDeep } = require("lodash/fp");
16
16
  const csvParser = require("../../../utilities/csvParser");
17
17
  const { handleRequest } = require("../row/external");
@@ -68,10 +68,8 @@ router
68
68
  // TODO: for now this builder endpoint is not authorized/secured, will need to be
69
69
  .get("/builder/:file*", controller.serveBuilder)
70
70
  .post("/api/attachments/process", (0, authorized_1.default)(permissions_1.BUILDER), controller.uploadFile)
71
- .post("/api/attachments/delete", (0, authorized_1.default)(permissions_1.BUILDER), controller.deleteObjects)
72
71
  .post("/api/beta/:feature", controller.toggleBetaUiFeature)
73
72
  .post("/api/attachments/:tableId/upload", (0, resourceId_1.paramResource)("tableId"), (0, authorized_1.default)(permissions_1.PermissionTypes.TABLE, permissions_1.PermissionLevels.WRITE), controller.uploadFile)
74
- .post("/api/attachments/:tableId/delete", (0, resourceId_1.paramResource)("tableId"), (0, authorized_1.default)(permissions_1.PermissionTypes.TABLE, permissions_1.PermissionLevels.WRITE), controller.deleteObjects)
75
73
  .get("/:appId/:path*", controller.serveApp)
76
74
  .get("/app/:appUrl/:path*", controller.serveApp)
77
75
  .post("/api/attachments/:datasourceId/url", (0, authorized_1.default)(permissions_1.PermissionTypes.TABLE, permissions_1.PermissionLevels.READ), controller.getSignedUploadURL);
@@ -18,10 +18,12 @@ const Queue = env.isTest()
18
18
  const { JobQueues } = require("../constants");
19
19
  const { utils } = require("@budibase/backend-core/redis");
20
20
  const { opts, redisProtocolUrl } = utils.getRedisOptions();
21
+ const listeners = require("./listeners");
21
22
  const CLEANUP_PERIOD_MS = 60 * 1000;
22
23
  const queueConfig = redisProtocolUrl || { redis: opts };
23
24
  let cleanupInternal = null;
24
25
  let automationQueue = new Queue(JobQueues.AUTOMATIONS, queueConfig);
26
+ listeners.addListeners(automationQueue);
25
27
  function cleanup() {
26
28
  return __awaiter(this, void 0, void 0, function* () {
27
29
  yield automationQueue.clean(CLEANUP_PERIOD_MS, "completed");
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.addListeners = void 0;
36
+ const automation = __importStar(require("../threads/automation"));
37
+ const addListeners = (queue) => {
38
+ logging(queue);
39
+ // handleStalled(queue)
40
+ };
41
+ exports.addListeners = addListeners;
42
+ const handleStalled = (queue) => {
43
+ queue.on("active", (job) => __awaiter(void 0, void 0, void 0, function* () {
44
+ yield automation.removeStalled(job);
45
+ }));
46
+ };
47
+ const logging = (queue) => {
48
+ var _a;
49
+ if ((_a = process.env.NODE_DEBUG) === null || _a === void 0 ? void 0 : _a.includes("bull")) {
50
+ queue
51
+ .on("error", (error) => {
52
+ // An error occurred.
53
+ console.error(`automation-event=error error=${JSON.stringify(error)}`);
54
+ })
55
+ .on("waiting", (jobId) => {
56
+ // A Job is waiting to be processed as soon as a worker is idling.
57
+ console.log(`automation-event=waiting jobId=${jobId}`);
58
+ })
59
+ .on("active", (job, jobPromise) => {
60
+ // A job has started. You can use `jobPromise.cancel()`` to abort it.
61
+ console.log(`automation-event=active jobId=${job.id}`);
62
+ })
63
+ .on("stalled", (job) => {
64
+ // A job has been marked as stalled. This is useful for debugging job
65
+ // workers that crash or pause the event loop.
66
+ console.error(`automation-event=stalled jobId=${job.id} job=${JSON.stringify(job)}`);
67
+ })
68
+ .on("progress", (job, progress) => {
69
+ // A job's progress was updated!
70
+ console.log(`automation-event=progress jobId=${job.id} progress=${progress}`);
71
+ })
72
+ .on("completed", (job, result) => {
73
+ // A job successfully completed with a `result`.
74
+ console.log(`automation-event=completed jobId=${job.id} result=${result}`);
75
+ })
76
+ .on("failed", (job, err) => {
77
+ // A job failed with reason `err`!
78
+ console.log(`automation-event=failed jobId=${job.id} error=${err}`);
79
+ })
80
+ .on("paused", () => {
81
+ // The queue has been paused.
82
+ console.log(`automation-event=paused`);
83
+ })
84
+ .on("resumed", (job) => {
85
+ // The queue has been resumed.
86
+ console.log(`automation-event=paused jobId=${job.id}`);
87
+ })
88
+ .on("cleaned", (jobs, type) => {
89
+ // Old jobs have been cleaned from the queue. `jobs` is an array of cleaned
90
+ // jobs, and `type` is the type of jobs cleaned.
91
+ console.log(`automation-event=cleaned length=${jobs.length} type=${type}`);
92
+ })
93
+ .on("drained", () => {
94
+ // Emitted every time the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed)
95
+ console.log(`automation-event=drained`);
96
+ })
97
+ .on("removed", (job) => {
98
+ // A job successfully removed.
99
+ console.log(`automation-event=removed jobId=${job.id}`);
100
+ });
101
+ }
102
+ };
@@ -56,9 +56,6 @@ function checkAppMetadata(apps) {
56
56
  for (let [key, errors] of Object.entries(metadata.automationErrors)) {
57
57
  const updated = [];
58
58
  for (let error of errors) {
59
- if (!error) {
60
- continue;
61
- }
62
59
  const startDate = error.split(backend_core_1.db.SEPARATOR)[2];
63
60
  if (startDate > maxStartDate) {
64
61
  updated.push(error);
@@ -52,10 +52,13 @@ const pro_1 = require("@budibase/pro");
52
52
  const WH_STEP_ID = triggerInfo_1.definitions.WEBHOOK.stepId;
53
53
  const CRON_STEP_ID = triggerInfo_1.definitions.CRON.stepId;
54
54
  const Runner = new threads_1.Thread(threads_1.ThreadType.AUTOMATION);
55
+ const jobMessage = (job, message) => {
56
+ return `app=${job.data.event.appId} automation=${job.data.automation._id} jobId=${job.id} trigger=${job.data.automation.definition.trigger.event} : ${message}`;
57
+ };
55
58
  function processEvent(job) {
56
59
  return __awaiter(this, void 0, void 0, function* () {
57
60
  try {
58
- console.log(`${job.data.automation.appId} automation ${job.data.automation._id} running`);
61
+ console.log(jobMessage(job, "running"));
59
62
  // need to actually await these so that an error can be captured properly
60
63
  const tenantId = backend_core_1.tenancy.getTenantIDFromAppID(job.data.event.appId);
61
64
  return yield backend_core_1.tenancy.doInTenant(tenantId, () => __awaiter(this, void 0, void 0, function* () {
@@ -65,7 +68,7 @@ function processEvent(job) {
65
68
  }
66
69
  catch (err) {
67
70
  const errJson = JSON.stringify(err);
68
- console.error(`${job.data.automation.appId} automation ${job.data.automation._id} was unable to run - ${errJson}`);
71
+ console.error(jobMessage(job, `was unable to run - ${errJson}`));
69
72
  console.trace(err);
70
73
  return { err };
71
74
  }
@@ -119,6 +122,7 @@ function disableCron(jobId, jobKey) {
119
122
  return __awaiter(this, void 0, void 0, function* () {
120
123
  yield bullboard_1.queue.removeRepeatableByKey(jobKey);
121
124
  yield bullboard_1.queue.removeJobs(jobId);
125
+ console.log(`jobId=${jobId} disabled`);
122
126
  });
123
127
  }
124
128
  exports.disableCron = disableCron;
@@ -17,7 +17,6 @@ const types_1 = require("@budibase/types");
17
17
  const utils_1 = require("../utils");
18
18
  const sqlTable_1 = __importDefault(require("./sqlTable"));
19
19
  const environment_1 = __importDefault(require("../../environment"));
20
- const utils_2 = require("./utils");
21
20
  const envLimit = environment_1.default.SQL_MAX_ROWS
22
21
  ? parseInt(environment_1.default.SQL_MAX_ROWS)
23
22
  : null;
@@ -117,13 +116,12 @@ class InternalBuilder {
117
116
  addFilters(query, filters, opts) {
118
117
  function iterate(structure, fn) {
119
118
  for (let [key, value] of Object.entries(structure)) {
120
- const updatedKey = (0, utils_2.removeKeyNumbering)(key);
121
- const isRelationshipField = updatedKey.includes(".");
119
+ const isRelationshipField = key.includes(".");
122
120
  if (!opts.relationship && !isRelationshipField) {
123
- fn(`${opts.tableName}.${updatedKey}`, value);
121
+ fn(`${opts.tableName}.${key}`, value);
124
122
  }
125
123
  if (opts.relationship && isRelationshipField) {
126
- fn(updatedKey, value);
124
+ fn(key, value);
127
125
  }
128
126
  }
129
127
  }
@@ -141,56 +139,6 @@ class InternalBuilder {
141
139
  ]);
142
140
  }
143
141
  };
144
- const contains = (mode, any = false) => {
145
- const fnc = allOr ? "orWhere" : "where";
146
- const rawFnc = `${fnc}Raw`;
147
- const not = mode === (filters === null || filters === void 0 ? void 0 : filters.notContains) ? "NOT " : "";
148
- function stringifyArray(value, quoteStyle = '"') {
149
- for (let i in value) {
150
- if (typeof value[i] === "string") {
151
- value[i] = `${quoteStyle}${value[i]}${quoteStyle}`;
152
- }
153
- }
154
- return `[${value.join(",")}]`;
155
- }
156
- if (this.client === utils_1.SqlClient.POSTGRES) {
157
- iterate(mode, (key, value) => {
158
- const wrap = any ? "" : "'";
159
- const containsOp = any ? "\\?| array" : "@>";
160
- const fieldNames = key.split(/\./g);
161
- const tableName = fieldNames[0];
162
- const columnName = fieldNames[1];
163
- // @ts-ignore
164
- query = query[rawFnc](`${not}"${tableName}"."${columnName}"::jsonb ${containsOp} ${wrap}${stringifyArray(value, any ? "'" : '"')}${wrap}`);
165
- });
166
- }
167
- else if (this.client === utils_1.SqlClient.MY_SQL) {
168
- const jsonFnc = any ? "JSON_OVERLAPS" : "JSON_CONTAINS";
169
- iterate(mode, (key, value) => {
170
- // @ts-ignore
171
- query = query[rawFnc](`${not}${jsonFnc}(${key}, '${stringifyArray(value)}')`);
172
- });
173
- }
174
- else {
175
- const andOr = mode === (filters === null || filters === void 0 ? void 0 : filters.containsAny) ? " OR " : " AND ";
176
- iterate(mode, (key, value) => {
177
- let statement = "";
178
- for (let i in value) {
179
- if (typeof value[i] === "string") {
180
- value[i] = `%"${value[i]}"%`;
181
- }
182
- else {
183
- value[i] = `%${value[i]}%`;
184
- }
185
- statement +=
186
- (statement ? andOr : "") +
187
- `LOWER(${likeKey(this.client, key)}) LIKE ?`;
188
- }
189
- // @ts-ignore
190
- query = query[rawFnc](`${not}(${statement})`, value);
191
- });
192
- }
193
- };
194
142
  if (!filters) {
195
143
  return query;
196
144
  }
@@ -264,13 +212,32 @@ class InternalBuilder {
264
212
  });
265
213
  }
266
214
  if (filters.contains) {
267
- contains(filters.contains);
268
- }
269
- if (filters.notContains) {
270
- contains(filters.notContains);
271
- }
272
- if (filters.containsAny) {
273
- contains(filters.containsAny, true);
215
+ const fnc = allOr ? "orWhere" : "where";
216
+ const rawFnc = `${fnc}Raw`;
217
+ if (this.client === utils_1.SqlClient.POSTGRES) {
218
+ iterate(filters.contains, (key, value) => {
219
+ const fieldNames = key.split(/\./g);
220
+ const tableName = fieldNames[0];
221
+ const columnName = fieldNames[1];
222
+ if (typeof value === "string") {
223
+ value = `"${value}"`;
224
+ }
225
+ // @ts-ignore
226
+ query = query[rawFnc](`"${tableName}"."${columnName}"::jsonb @> '[${value}]'`);
227
+ });
228
+ }
229
+ else if (this.client === utils_1.SqlClient.MY_SQL) {
230
+ iterate(filters.contains, (key, value) => {
231
+ if (typeof value === "string") {
232
+ value = `"${value}"`;
233
+ }
234
+ // @ts-ignore
235
+ query = query[rawFnc](`JSON_CONTAINS(${key}, '${value}')`);
236
+ });
237
+ }
238
+ else {
239
+ iterate(filters.contains, like);
240
+ }
274
241
  }
275
242
  return query;
276
243
  }
@@ -581,3 +548,4 @@ class SqlQueryBuilder extends sqlTable_1.default {
581
548
  }
582
549
  }
583
550
  exports.default = SqlQueryBuilder;
551
+ module.exports = SqlQueryBuilder;
@@ -1,16 +1,30 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.removeKeyNumbering = void 0;
4
- const QUERY_START_REGEX = /\d[0-9]*:/g;
5
- function removeKeyNumbering(key) {
6
- if (typeof key === "string" && key.match(QUERY_START_REGEX) != null) {
7
- const parts = key.split(":");
8
- // remove the number
9
- parts.shift();
10
- return parts.join(":");
12
+ var DatasourceUtils;
13
+ (function (DatasourceUtils) {
14
+ const { integrations } = require("../index");
15
+ function makeExternalQuery(datasource, json) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ const Integration = integrations[datasource.source];
18
+ // query is the opinionated function
19
+ if (Integration.prototype.query) {
20
+ const integration = new Integration(datasource.config);
21
+ return integration.query(json);
22
+ }
23
+ else {
24
+ throw "Datasource does not support query.";
25
+ }
26
+ });
11
27
  }
12
- else {
13
- return key;
14
- }
15
- }
16
- exports.removeKeyNumbering = removeKeyNumbering;
28
+ DatasourceUtils.makeExternalQuery = makeExternalQuery;
29
+ module.exports.makeExternalQuery = makeExternalQuery;
30
+ })(DatasourceUtils || (DatasourceUtils = {}));
@@ -8,16 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  const types_1 = require("@budibase/types");
16
13
  const utils_1 = require("./utils");
17
- const sql_1 = __importDefault(require("./base/sql"));
18
14
  var MSSQLModule;
19
15
  (function (MSSQLModule) {
20
16
  const sqlServer = require("mssql");
17
+ const Sql = require("./base/sql");
21
18
  const DEFAULT_SCHEMA = "dbo";
22
19
  const SCHEMA = {
23
20
  docs: "https://github.com/tediousjs/node-mssql",
@@ -72,7 +69,7 @@ var MSSQLModule;
72
69
  },
73
70
  },
74
71
  };
75
- class SqlServerIntegration extends sql_1.default {
72
+ class SqlServerIntegration extends Sql {
76
73
  constructor(config) {
77
74
  super(utils_1.SqlClient.MS_SQL);
78
75
  this.index = 0;
@@ -80,11 +80,10 @@ var MongoDBModule;
80
80
  if (json[field] instanceof Object) {
81
81
  json[field] = self.createObjectIds(json[field]);
82
82
  }
83
- if ((field === "_id" || (field === null || field === void 0 ? void 0 : field.startsWith("$"))) &&
84
- typeof json[field] === "string") {
85
- const id = (_a = json[field].match(/(?<=objectid\(['"]).*(?=['"]\))/gi)) === null || _a === void 0 ? void 0 : _a[0];
83
+ if (field === "_id" && typeof json[field] === "string") {
84
+ const id = (_a = json["_id"].match(/(?<=objectid\(['"]).*(?=['"]\))/gi)) === null || _a === void 0 ? void 0 : _a[0];
86
85
  if (id) {
87
- json[field] = mongodb_1.ObjectID.createFromHexString(id);
86
+ json["_id"] = mongodb_1.ObjectID.createFromHexString(id);
88
87
  }
89
88
  }
90
89
  }
@@ -99,33 +98,10 @@ var MongoDBModule;
99
98
  return interpolateObjectIds(json);
100
99
  }
101
100
  parseQueryParams(params, mode) {
102
- var _a, _b, _c;
103
- let queryParams = [];
104
- let openCount = 0;
105
- let inQuotes = false;
106
- let i = 0;
107
- let startIndex = 0;
108
- for (let c of params) {
109
- if (c === '"' && i > 0 && params[i - 1] !== "\\") {
110
- inQuotes = !inQuotes;
111
- }
112
- if (c === "{" && !inQuotes) {
113
- openCount++;
114
- if (openCount === 1) {
115
- startIndex = i;
116
- }
117
- }
118
- else if (c === "}" && !inQuotes) {
119
- if (openCount === 1) {
120
- queryParams.push(JSON.parse(params.substring(startIndex, i + 1)));
121
- }
122
- openCount--;
123
- }
124
- i++;
125
- }
126
- let group1 = (_a = queryParams[0]) !== null && _a !== void 0 ? _a : {};
127
- let group2 = (_b = queryParams[1]) !== null && _b !== void 0 ? _b : {};
128
- let group3 = (_c = queryParams[2]) !== null && _c !== void 0 ? _c : {};
101
+ let queryParams = params.split(/(?<=}),[\n\s]*(?={)/g);
102
+ let group1 = queryParams[0] ? JSON.parse(queryParams[0]) : {};
103
+ let group2 = queryParams[1] ? JSON.parse(queryParams[1]) : {};
104
+ let group3 = queryParams[2] ? JSON.parse(queryParams[2]) : {};
129
105
  if (mode === "update") {
130
106
  return {
131
107
  filter: group1,
@@ -183,10 +159,7 @@ var MongoDBModule;
183
159
  return yield collection.findOne(json);
184
160
  }
185
161
  case "findOneAndUpdate": {
186
- if (typeof query.json === "string") {
187
- json = this.parseQueryParams(query.json, "update");
188
- }
189
- let findAndUpdateJson = this.createObjectIds(json);
162
+ let findAndUpdateJson = json;
190
163
  return yield collection.findOneAndUpdate(findAndUpdateJson.filter, findAndUpdateJson.update, findAndUpdateJson.options);
191
164
  }
192
165
  case "count": {
@@ -16,10 +16,10 @@ const types_1 = require("@budibase/types");
16
16
  const utils_1 = require("./utils");
17
17
  const dayjs_1 = __importDefault(require("dayjs"));
18
18
  const { NUMBER_REGEX } = require("../utilities");
19
- const sql_1 = __importDefault(require("./base/sql"));
20
19
  var MySQLModule;
21
20
  (function (MySQLModule) {
22
21
  const mysql = require("mysql2/promise");
22
+ const Sql = require("./base/sql");
23
23
  const SCHEMA = {
24
24
  docs: "https://github.com/sidorares/node-mysql2",
25
25
  plus: true,
@@ -96,7 +96,7 @@ var MySQLModule;
96
96
  }
97
97
  return bindings;
98
98
  }
99
- class MySQLIntegration extends sql_1.default {
99
+ class MySQLIntegration extends Sql {
100
100
  constructor(config) {
101
101
  super(utils_1.SqlClient.MY_SQL);
102
102
  this.tables = {};