@budibase/server 0.9.171 → 0.9.173-alpha.2

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 (261) hide show
  1. package/__mocks__/{mysql.ts → mysql2.ts} +0 -0
  2. package/builder/assets/{index.dbc6728e.css → index.7469e1e4.css} +2 -2
  3. package/builder/assets/{index.cf0febb9.js → index.8a8f7849.js} +34 -34
  4. package/builder/assets/{vendor.54435e8f.js → vendor.278a305c.js} +1 -1
  5. package/builder/index.html +3 -3
  6. package/coverage/clover.xml +973 -849
  7. package/coverage/coverage-final.json +47 -46
  8. package/coverage/lcov-report/api/controllers/analytics.js.html +21 -9
  9. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/application.js.html +186 -84
  11. package/coverage/lcov-report/api/controllers/auth.js.html +37 -10
  12. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/backup.js.html +6 -9
  14. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/dev.js.html +41 -17
  18. package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/index.html +71 -71
  20. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/permission.js.html +7 -4
  24. package/coverage/lcov-report/api/controllers/query.js.html +129 -24
  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 +5 -5
  29. package/coverage/lcov-report/api/controllers/row/index.js.html +15 -15
  30. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/screen.js.html +9 -9
  34. package/coverage/lcov-report/api/controllers/script.js.html +12 -57
  35. package/coverage/lcov-report/api/controllers/table/index.html +28 -28
  36. package/coverage/lcov-report/api/controllers/table/index.js.html +16 -37
  37. package/coverage/lcov-report/api/controllers/table/utils.js.html +279 -33
  38. package/coverage/lcov-report/api/controllers/templates.js.html +49 -13
  39. package/coverage/lcov-report/api/controllers/user.js.html +3 -3
  40. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/view/index.html +19 -19
  42. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  43. package/coverage/lcov-report/api/controllers/view/utils.js.html +8 -8
  44. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +54 -15
  45. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  46. package/coverage/lcov-report/api/index.html +1 -1
  47. package/coverage/lcov-report/api/index.js.html +3 -3
  48. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/application.js.html +5 -2
  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 +26 -11
  59. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/index.html +9 -9
  61. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/query.js.html +9 -3
  67. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/static.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  78. package/coverage/lcov-report/automations/actions.js.html +31 -10
  79. package/coverage/lcov-report/automations/automationUtils.js.html +14 -86
  80. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  81. package/coverage/lcov-report/automations/index.html +37 -37
  82. package/coverage/lcov-report/automations/index.js.html +1 -1
  83. package/coverage/lcov-report/automations/steps/bash.js.html +10 -7
  84. package/coverage/lcov-report/automations/steps/createRow.js.html +2 -2
  85. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/deleteRow.js.html +8 -5
  87. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/executeQuery.js.html +10 -7
  89. package/coverage/lcov-report/automations/steps/executeScript.js.html +10 -7
  90. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/index.html +57 -57
  92. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +10 -7
  94. package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -7
  95. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +10 -7
  96. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/updateRow.js.html +14 -14
  99. package/coverage/lcov-report/automations/steps/utils.js.html +10 -10
  100. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  101. package/coverage/lcov-report/automations/thread.js.html +54 -12
  102. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  108. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  109. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  110. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  111. package/coverage/lcov-report/automations/utils.js.html +28 -28
  112. package/coverage/lcov-report/constants/index.html +1 -1
  113. package/coverage/lcov-report/constants/index.js.html +5 -2
  114. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  115. package/coverage/lcov-report/constants/screens.js.html +2 -2
  116. package/coverage/lcov-report/db/client.js.html +1 -1
  117. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  118. package/coverage/lcov-report/db/index.html +1 -1
  119. package/coverage/lcov-report/db/index.js.html +1 -1
  120. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +12 -12
  121. package/coverage/lcov-report/db/linkedRows/index.html +18 -18
  122. package/coverage/lcov-report/db/linkedRows/index.js.html +47 -26
  123. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  124. package/coverage/lcov-report/db/newid.js.html +2 -2
  125. package/coverage/lcov-report/db/utils.js.html +17 -17
  126. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  127. package/coverage/lcov-report/events/index.html +1 -1
  128. package/coverage/lcov-report/events/index.js.html +1 -1
  129. package/coverage/lcov-report/events/utils.js.html +1 -1
  130. package/coverage/lcov-report/index.html +107 -107
  131. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  132. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  133. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  134. package/coverage/lcov-report/middleware/authorized.js.html +2 -2
  135. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  136. package/coverage/lcov-report/middleware/currentapp.js.html +52 -25
  137. package/coverage/lcov-report/middleware/index.html +15 -15
  138. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  139. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  140. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  141. package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
  142. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  143. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  144. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  145. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  146. package/coverage/lcov-report/utilities/global.js.html +27 -27
  147. package/coverage/lcov-report/utilities/index.html +32 -17
  148. package/coverage/lcov-report/utilities/index.js.html +4 -4
  149. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +29 -8
  150. package/coverage/lcov-report/utilities/queue/index.html +15 -15
  151. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  152. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  153. package/coverage/lcov-report/utilities/rowProcessor/index.html +14 -14
  154. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +38 -8
  155. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  156. package/coverage/lcov-report/utilities/scriptRunner.js.html +143 -0
  157. package/coverage/lcov-report/utilities/security.js.html +1 -1
  158. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  159. package/coverage/lcov-report/utilities/users.js.html +1 -1
  160. package/coverage/lcov-report/utilities/workerRequests.js.html +19 -19
  161. package/coverage/lcov.info +1692 -1452
  162. package/dist/api/controllers/analytics.js +4 -0
  163. package/dist/api/controllers/application.js +185 -171
  164. package/dist/api/controllers/auth.js +12 -2
  165. package/dist/api/controllers/backup.js +4 -4
  166. package/dist/api/controllers/deploy/index.js +3 -16
  167. package/dist/api/controllers/dev.js +17 -11
  168. package/dist/api/controllers/permission.js +1 -0
  169. package/dist/api/controllers/query.js +26 -8
  170. package/dist/api/controllers/row/ExternalRequest.js +46 -5
  171. package/dist/api/controllers/script.js +4 -16
  172. package/dist/api/controllers/table/index.js +5 -10
  173. package/dist/api/controllers/table/utils.js +83 -10
  174. package/dist/api/controllers/templates.js +18 -3
  175. package/dist/api/controllers/view/viewBuilder.js +15 -1
  176. package/dist/api/routes/application.js +1 -0
  177. package/dist/api/routes/dev.js +8 -4
  178. package/dist/api/routes/query.js +3 -1
  179. package/dist/api/routes/tests/utilities/TestFunctions.js +7 -9
  180. package/dist/automations/actions.js +9 -3
  181. package/dist/automations/automationUtils.js +8 -29
  182. package/dist/automations/steps/bash.js +2 -1
  183. package/dist/automations/steps/createRow.js +1 -1
  184. package/dist/automations/steps/deleteRow.js +2 -1
  185. package/dist/automations/steps/executeQuery.js +2 -1
  186. package/dist/automations/steps/executeScript.js +2 -1
  187. package/dist/automations/steps/outgoingWebhook.js +2 -1
  188. package/dist/automations/steps/queryRows.js +2 -1
  189. package/dist/automations/steps/sendSmtpEmail.js +2 -1
  190. package/dist/automations/steps/updateRow.js +6 -2
  191. package/dist/automations/thread.js +14 -3
  192. package/dist/constants/index.js +1 -0
  193. package/dist/db/linkedRows/index.js +9 -6
  194. package/dist/integrations/base/sql.js +4 -4
  195. package/dist/integrations/mysql.js +1 -1
  196. package/dist/integrations/utils.js +17 -1
  197. package/dist/middleware/currentapp.js +8 -2
  198. package/dist/package.json +7 -6
  199. package/dist/tests/utilities/TestConfiguration.js +34 -19
  200. package/dist/tests/utilities/controllers.js +1 -0
  201. package/dist/tsconfig.tsbuildinfo +1 -1
  202. package/dist/utilities/fileSystem/index.js +49 -33
  203. package/dist/utilities/global.js +1 -1
  204. package/dist/utilities/queue/inMemoryQueue.js +6 -0
  205. package/dist/utilities/rowProcessor/index.js +8 -0
  206. package/dist/utilities/scriptRunner.js +19 -0
  207. package/package.json +8 -7
  208. package/scripts/jestSetup.js +2 -0
  209. package/src/api/controllers/analytics.js +4 -0
  210. package/src/api/controllers/application.js +43 -9
  211. package/src/api/controllers/auth.js +12 -3
  212. package/src/api/controllers/backup.js +4 -5
  213. package/src/api/controllers/deploy/index.js +3 -18
  214. package/src/api/controllers/dev.js +16 -8
  215. package/src/api/controllers/permission.js +1 -0
  216. package/src/api/controllers/query.js +46 -11
  217. package/src/api/controllers/row/ExternalRequest.ts +53 -4
  218. package/src/api/controllers/script.js +4 -19
  219. package/src/api/controllers/table/index.js +5 -12
  220. package/src/api/controllers/table/utils.js +94 -12
  221. package/src/api/controllers/templates.js +17 -5
  222. package/src/api/controllers/view/tests/__snapshots__/viewBuilder.spec.js.snap +1 -1
  223. package/src/api/controllers/view/viewBuilder.js +14 -1
  224. package/src/api/routes/application.js +1 -0
  225. package/src/api/routes/dev.js +9 -4
  226. package/src/api/routes/query.js +3 -1
  227. package/src/api/routes/tests/auth.spec.js +1 -2
  228. package/src/api/routes/tests/permissions.spec.js +3 -0
  229. package/src/api/routes/tests/query.spec.js +2 -2
  230. package/src/api/routes/tests/routing.spec.js +24 -8
  231. package/src/api/routes/tests/user.spec.js +1 -1
  232. package/src/api/routes/tests/utilities/TestFunctions.js +7 -9
  233. package/src/api/routes/tests/webhook.spec.js +4 -1
  234. package/src/automations/actions.js +10 -3
  235. package/src/automations/automationUtils.js +7 -31
  236. package/src/automations/steps/bash.js +2 -1
  237. package/src/automations/steps/createRow.js +1 -1
  238. package/src/automations/steps/deleteRow.js +2 -1
  239. package/src/automations/steps/executeQuery.js +2 -1
  240. package/src/automations/steps/executeScript.js +2 -1
  241. package/src/automations/steps/outgoingWebhook.js +2 -1
  242. package/src/automations/steps/queryRows.js +2 -1
  243. package/src/automations/steps/sendSmtpEmail.js +2 -1
  244. package/src/automations/steps/updateRow.js +6 -6
  245. package/src/automations/thread.js +17 -3
  246. package/src/constants/index.js +1 -0
  247. package/src/db/linkedRows/index.js +14 -7
  248. package/src/integrations/base/sql.ts +11 -3
  249. package/src/integrations/mysql.ts +1 -1
  250. package/src/integrations/tests/mongo.spec.js +10 -6
  251. package/src/integrations/tests/mysql.spec.js +1 -1
  252. package/src/integrations/utils.ts +18 -0
  253. package/src/middleware/currentapp.js +11 -2
  254. package/src/middleware/tests/currentapp.spec.js +3 -3
  255. package/src/tests/utilities/TestConfiguration.js +47 -19
  256. package/src/tests/utilities/controllers.js +1 -0
  257. package/src/utilities/fileSystem/index.js +65 -43
  258. package/src/utilities/global.js +1 -1
  259. package/src/utilities/queue/inMemoryQueue.js +7 -0
  260. package/src/utilities/rowProcessor/index.js +10 -0
  261. package/src/utilities/scriptRunner.js +21 -0
@@ -12,6 +12,7 @@ const rowController = require("../../api/controllers/row");
12
12
  const tableController = require("../../api/controllers/table");
13
13
  const { FieldTypes } = require("../../constants");
14
14
  const { buildCtx } = require("./utils");
15
+ const automationUtils = require("../automationUtils");
15
16
  const SortOrders = {
16
17
  ASCENDING: "ascending",
17
18
  DESCENDING: "descending",
@@ -119,7 +120,7 @@ exports.run = function ({ inputs, appId }) {
119
120
  catch (err) {
120
121
  return {
121
122
  success: false,
122
- response: err,
123
+ response: automationUtils.getError(err),
123
124
  };
124
125
  }
125
126
  });
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  const { sendSmtpEmail } = require("../../utilities/workerRequests");
12
+ const automationUtils = require("../automationUtils");
12
13
  exports.definition = {
13
14
  description: "Send an email using SMTP",
14
15
  tagline: "Send SMTP email to {{inputs.to}}",
@@ -71,7 +72,7 @@ exports.run = function ({ inputs }) {
71
72
  catch (err) {
72
73
  return {
73
74
  success: false,
74
- response: err,
75
+ response: automationUtils.getError(err),
75
76
  };
76
77
  }
77
78
  });
@@ -73,6 +73,7 @@ exports.run = function ({ inputs, appId, emitter }) {
73
73
  },
74
74
  };
75
75
  }
76
+ const tableId = inputs.row.tableId;
76
77
  // clear any falsy properties so that they aren't updated
77
78
  for (let propKey of Object.keys(inputs.row)) {
78
79
  if (!inputs.row[propKey] || inputs.row[propKey] === "") {
@@ -84,10 +85,13 @@ exports.run = function ({ inputs, appId, emitter }) {
84
85
  body: Object.assign(Object.assign({}, inputs.row), { _id: inputs.rowId }),
85
86
  params: {
86
87
  rowId: inputs.rowId,
88
+ tableId: tableId,
87
89
  },
88
90
  });
89
91
  try {
90
- inputs.row = yield automationUtils.cleanUpRowById(appId, inputs.rowId, inputs.row);
92
+ if (tableId) {
93
+ inputs.row = yield automationUtils.cleanUpRow(appId, tableId, inputs.row);
94
+ }
91
95
  yield rowController.patch(ctx);
92
96
  return {
93
97
  row: ctx.body,
@@ -100,7 +104,7 @@ exports.run = function ({ inputs, appId, emitter }) {
100
104
  catch (err) {
101
105
  return {
102
106
  success: false,
103
- response: err,
107
+ response: automationUtils.getError(err),
104
108
  };
105
109
  }
106
110
  });
@@ -19,6 +19,7 @@ const { doInTenant } = require("@budibase/auth/tenancy");
19
19
  const env = require("../environment");
20
20
  const usage = require("../utilities/usageQuota");
21
21
  const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId;
22
+ const STOPPED_STATUS = { success: false, status: "STOPPED" };
22
23
  /**
23
24
  * The automation orchestrator is a class responsible for executing automations.
24
25
  * It handles the context of the automation and makes sure each step gets the correct
@@ -77,7 +78,13 @@ class Orchestrator {
77
78
  return __awaiter(this, void 0, void 0, function* () {
78
79
  let automation = this._automation;
79
80
  const app = yield this.getApp();
81
+ let stopped = false;
80
82
  for (let step of automation.definition.steps) {
83
+ // execution stopped, record state for that
84
+ if (stopped) {
85
+ this.updateExecutionOutput(step.id, step.stepId, {}, STOPPED_STATUS);
86
+ continue;
87
+ }
81
88
  let stepFn = yield this.getStepFunctionality(step.stepId);
82
89
  step.inputs = yield processObject(step.inputs, this._context);
83
90
  step.inputs = automationUtils.cleanInputValues(step.inputs, step.schema.inputs);
@@ -92,10 +99,14 @@ class Orchestrator {
92
99
  context: this._context,
93
100
  });
94
101
  });
102
+ this._context.steps.push(outputs);
103
+ // if filter causes us to stop execution don't break the loop, set a var
104
+ // so that we can finish iterating through the steps and record that it stopped
95
105
  if (step.stepId === FILTER_STEP_ID && !outputs.success) {
96
- break;
106
+ stopped = true;
107
+ this.updateExecutionOutput(step.id, step.stepId, step.inputs, Object.assign(Object.assign({}, outputs), STOPPED_STATUS));
108
+ continue;
97
109
  }
98
- this._context.steps.push(outputs);
99
110
  this.updateExecutionOutput(step.id, step.stepId, step.inputs, outputs);
100
111
  }
101
112
  catch (err) {
@@ -105,7 +116,7 @@ class Orchestrator {
105
116
  }
106
117
  // Increment quota for automation runs
107
118
  if (!env.SELF_HOSTED && !isDevAppID(this._appId)) {
108
- usage.update(usage.Properties.AUTOMATION, 1);
119
+ yield usage.update(usage.Properties.AUTOMATION, 1);
109
120
  }
110
121
  return this.executionOutput;
111
122
  });
@@ -39,6 +39,7 @@ exports.FieldTypes = {
39
39
  FORMULA: "formula",
40
40
  AUTO: "auto",
41
41
  JSON: "json",
42
+ INTERNAL: "internal",
42
43
  };
43
44
  exports.RelationshipTypes = {
44
45
  ONE_TO_MANY: "one-to-many",
@@ -69,7 +69,9 @@ function getFullLinkedDocs(ctx, appId, links) {
69
69
  const uniqueRowIds = [...new Set(linkedRowIds)];
70
70
  let dbRows = (yield db.allDocs(getMultiIDParams(uniqueRowIds))).rows.map(row => row.doc);
71
71
  // convert the unique db rows back to a full list of linked rows
72
- const linked = linkedRowIds.map(id => dbRows.find(row => row._id === id));
72
+ const linked = linkedRowIds
73
+ .map(id => dbRows.find(row => row && row._id === id))
74
+ .filter(row => row != null);
73
75
  // need to handle users as specific cases
74
76
  let [users, other] = partition(linked, linkRow => linkRow._id.startsWith(USER_METDATA_PREFIX));
75
77
  users = yield getGlobalUsersFromMetadata(appId, users);
@@ -156,12 +158,13 @@ exports.attachFullLinkedDocs = (ctx, table, rows) => __awaiter(void 0, void 0, v
156
158
  row[link.fieldName] = [];
157
159
  }
158
160
  const linkedRow = linked.find(row => row._id === link.id);
159
- const linkedTableId = linkedRow.tableId || getRelatedTableForField(table, link.fieldName);
160
- const linkedTable = yield getLinkedTable(db, linkedTableId, linkedTables);
161
- if (!linkedRow || !linkedTable) {
162
- continue;
161
+ if (linkedRow) {
162
+ const linkedTableId = linkedRow.tableId || getRelatedTableForField(table, link.fieldName);
163
+ const linkedTable = yield getLinkedTable(db, linkedTableId, linkedTables);
164
+ if (linkedTable) {
165
+ row[link.fieldName].push(processFormulas(linkedTable, linkedRow));
166
+ }
163
167
  }
164
- row[link.fieldName].push(processFormulas(linkedTable, linkedRow));
165
168
  }
166
169
  }
167
170
  return rows;
@@ -80,7 +80,7 @@ function addFilters(tableName, query, filters) {
80
80
  }
81
81
  return query;
82
82
  }
83
- function addRelationships(query, fromTable, relationships) {
83
+ function addRelationships(knex, query, fields, fromTable, relationships) {
84
84
  if (!relationships) {
85
85
  return query;
86
86
  }
@@ -88,7 +88,7 @@ function addRelationships(query, fromTable, relationships) {
88
88
  const from = relationship.from, to = relationship.to, toTable = relationship.tableName;
89
89
  if (!relationship.through) {
90
90
  // @ts-ignore
91
- query = query.leftJoin(toTable, `${fromTable}.${from}`, `${relationship.tableName}.${to}`);
91
+ query = query.leftJoin(toTable, `${fromTable}.${from}`, `${toTable}.${to}`);
92
92
  }
93
93
  else {
94
94
  const throughTable = relationship.through;
@@ -100,7 +100,7 @@ function addRelationships(query, fromTable, relationships) {
100
100
  .leftJoin(toTable, `${toTable}.${toPrimary}`, `${throughTable}.${to}`);
101
101
  }
102
102
  }
103
- return query;
103
+ return query.limit(BASE_LIMIT);
104
104
  }
105
105
  function buildCreate(knex, json, opts) {
106
106
  const { endpoint, body } = json;
@@ -165,7 +165,7 @@ function buildRead(knex, json, limit) {
165
165
  [tableName]: query,
166
166
  }).select(selectStatement);
167
167
  // handle joins
168
- return addRelationships(preQuery, tableName, relationships);
168
+ return addRelationships(knex, preQuery, selectStatement, tableName, relationships);
169
169
  }
170
170
  function buildUpdate(knex, json, opts) {
171
171
  const { endpoint, body, filters } = json;
@@ -13,7 +13,7 @@ const datasource_1 = require("../definitions/datasource");
13
13
  const utils_1 = require("./utils");
14
14
  var MySQLModule;
15
15
  (function (MySQLModule) {
16
- const mysql = require("mysql");
16
+ const mysql = require("mysql2");
17
17
  const Sql = require("./base/sql");
18
18
  const { buildExternalTableId, convertType, copyExistingPropsOver, } = require("./utils");
19
19
  const { FieldTypes } = require("../constants");
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.copyExistingPropsOver = exports.isIsoDateString = exports.isSQL = exports.getSqlQuery = exports.convertType = exports.breakRowIdField = exports.generateRowIdField = exports.breakExternalTableId = exports.buildExternalTableId = exports.isExternalTable = void 0;
3
+ exports.copyExistingPropsOver = exports.isIsoDateString = exports.isSQL = exports.getSqlQuery = exports.convertType = exports.breakRowIdField = exports.convertRowId = exports.isRowId = exports.generateRowIdField = exports.breakExternalTableId = exports.buildExternalTableId = exports.isExternalTable = void 0;
4
4
  const datasource_1 = require("../definitions/datasource");
5
5
  const { DocumentTypes, SEPARATOR } = require("../db/utils");
6
6
  const { FieldTypes } = require("../constants");
7
7
  const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`;
8
+ const ROW_ID_REGEX = /^\[.*]$/g;
8
9
  function isExternalTable(tableId) {
9
10
  return tableId.includes(DocumentTypes.DATASOURCE);
10
11
  }
@@ -31,6 +32,21 @@ function generateRowIdField(keyProps = []) {
31
32
  return encodeURIComponent(JSON.stringify(keyProps).replace(/"/g, "'"));
32
33
  }
33
34
  exports.generateRowIdField = generateRowIdField;
35
+ function isRowId(field) {
36
+ return (Array.isArray(field) ||
37
+ (typeof field === "string" && field.match(ROW_ID_REGEX) != null));
38
+ }
39
+ exports.isRowId = isRowId;
40
+ function convertRowId(field) {
41
+ if (Array.isArray(field)) {
42
+ return field[0];
43
+ }
44
+ if (typeof field === "string" && field.match(ROW_ID_REGEX) != null) {
45
+ return field.substring(1, field.length - 1);
46
+ }
47
+ return field;
48
+ }
49
+ exports.convertRowId = convertRowId;
34
50
  // should always return an array
35
51
  function breakRowIdField(_id) {
36
52
  if (!_id) {
@@ -12,7 +12,7 @@ const { getAppId, setCookie, getCookie, clearCookie } = require("@budibase/auth"
12
12
  const { Cookies } = require("@budibase/auth").constants;
13
13
  const { getRole } = require("@budibase/auth/roles");
14
14
  const { BUILTIN_ROLE_IDS } = require("@budibase/auth/roles");
15
- const { generateUserMetadataID } = require("../db/utils");
15
+ const { generateUserMetadataID, isDevAppID } = require("../db/utils");
16
16
  const { dbExists } = require("@budibase/auth/db");
17
17
  const { isUserInAppTenant } = require("@budibase/auth/tenancy");
18
18
  const { getCachedSelf } = require("../utilities/global");
@@ -43,6 +43,12 @@ module.exports = (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
43
43
  // if the request app ID wasn't set, update it with the cookie
44
44
  requestAppId = requestAppId || appId;
45
45
  }
46
+ // deny access to application preview
47
+ if (isDevAppID(requestAppId) &&
48
+ (!ctx.user || !ctx.user.builder || !ctx.user.builder.global)) {
49
+ clearCookie(ctx, Cookies.CurrentApp);
50
+ return ctx.redirect("/");
51
+ }
46
52
  let appId, roleId = BUILTIN_ROLE_IDS.PUBLIC;
47
53
  if (!ctx.user) {
48
54
  // not logged in, try to set a cookie for public apps
@@ -53,7 +59,7 @@ module.exports = (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
53
59
  const globalUser = yield getCachedSelf(ctx, requestAppId);
54
60
  appId = requestAppId;
55
61
  // retrieving global user gets the right role
56
- roleId = globalUser.roleId || BUILTIN_ROLE_IDS.BASIC;
62
+ roleId = globalUser.roleId || roleId;
57
63
  }
58
64
  // nothing more to do
59
65
  if (!appId) {
package/dist/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "0.9.170",
4
+ "version": "0.9.173-alpha.1",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.js",
7
7
  "repository": {
@@ -68,13 +68,13 @@
68
68
  "author": "Budibase",
69
69
  "license": "AGPL-3.0-or-later",
70
70
  "dependencies": {
71
- "@budibase/auth": "^0.9.170",
72
- "@budibase/client": "^0.9.170",
73
- "@budibase/string-templates": "^0.9.170",
71
+ "@budibase/auth": "^0.9.173-alpha.1",
72
+ "@budibase/client": "^0.9.173-alpha.1",
73
+ "@budibase/string-templates": "^0.9.173-alpha.1",
74
74
  "@elastic/elasticsearch": "7.10.0",
75
75
  "@koa/router": "8.0.0",
76
76
  "@sendgrid/mail": "7.1.1",
77
- "@sentry/node": "5.19.2",
77
+ "@sentry/node": "^6.0.0",
78
78
  "airtable": "0.10.1",
79
79
  "arangojs": "7.2.0",
80
80
  "aws-sdk": "^2.767.0",
@@ -103,7 +103,7 @@
103
103
  "memorystream": "^0.3.1",
104
104
  "mongodb": "3.6.3",
105
105
  "mssql": "6.2.3",
106
- "mysql": "2.18.1",
106
+ "mysql2": "^2.3.1",
107
107
  "node-fetch": "2.6.0",
108
108
  "open": "7.3.0",
109
109
  "pg": "8.5.1",
@@ -119,6 +119,7 @@
119
119
  "to-json-schema": "0.2.5",
120
120
  "uuid": "3.3.2",
121
121
  "validate.js": "0.13.1",
122
+ "vm2": "^3.9.3",
122
123
  "yargs": "13.2.4",
123
124
  "zlib": "1.0.5"
124
125
  },
@@ -24,7 +24,6 @@ const CouchDB = require("../../db");
24
24
  auth.init(CouchDB);
25
25
  const GLOBAL_USER_ID = "us_uuid1";
26
26
  const EMAIL = "babs@babs.com";
27
- const PASSWORD = "babs_password";
28
27
  class TestConfiguration {
29
28
  constructor(openServer = true) {
30
29
  if (openServer) {
@@ -62,7 +61,7 @@ class TestConfiguration {
62
61
  return request.body;
63
62
  });
64
63
  }
65
- globalUser(id = GLOBAL_USER_ID, builder = true, roles) {
64
+ globalUser({ id = GLOBAL_USER_ID, builder = true, email = EMAIL, roles, } = {}) {
66
65
  return __awaiter(this, void 0, void 0, function* () {
67
66
  const db = getGlobalDB(TENANT_ID);
68
67
  let existing;
@@ -70,13 +69,16 @@ class TestConfiguration {
70
69
  existing = yield db.get(id);
71
70
  }
72
71
  catch (err) {
73
- existing = {};
72
+ existing = { email };
74
73
  }
75
74
  const user = Object.assign(Object.assign({ _id: id }, existing), { roles: roles || {}, tenantId: TENANT_ID });
76
75
  yield createASession(id, { sessionId: "sessionid", tenantId: TENANT_ID });
77
76
  if (builder) {
78
77
  user.builder = { global: true };
79
78
  }
79
+ else {
80
+ user.builder = { global: false };
81
+ }
80
82
  const resp = yield db.put(user);
81
83
  return Object.assign({ _rev: resp._rev }, user);
82
84
  });
@@ -120,28 +122,42 @@ class TestConfiguration {
120
122
  }
121
123
  return headers;
122
124
  }
123
- publicHeaders() {
125
+ publicHeaders({ prodApp = true } = {}) {
126
+ const appId = prodApp ? this.prodAppId : this.appId;
124
127
  const headers = {
125
128
  Accept: "application/json",
126
129
  };
127
- if (this.appId) {
128
- headers[Headers.APP_ID] = this.appId;
130
+ if (appId) {
131
+ headers[Headers.APP_ID] = appId;
129
132
  }
130
133
  return headers;
131
134
  }
132
- roleHeaders({ email = EMAIL, roleId = BUILTIN_ROLE_IDS.ADMIN, builder = false, }) {
135
+ roleHeaders({ email = EMAIL, roleId = BUILTIN_ROLE_IDS.ADMIN, builder = false, prodApp = true, } = {}) {
133
136
  return __awaiter(this, void 0, void 0, function* () {
134
- return this.login(email, PASSWORD, { roleId, builder });
137
+ return this.login({ email, roleId, builder, prodApp });
135
138
  });
136
139
  }
137
140
  createApp(appName) {
138
141
  return __awaiter(this, void 0, void 0, function* () {
142
+ // create dev app
139
143
  this.app = yield this._req({ name: appName }, null, controllers.app.create);
140
144
  this.appId = this.app.appId;
145
+ // create production app
146
+ this.prodApp = yield this.deploy();
147
+ this.prodAppId = this.prodApp.appId;
148
+ this.allApps.push(this.prodApp);
141
149
  this.allApps.push(this.app);
142
150
  return this.app;
143
151
  });
144
152
  }
153
+ deploy() {
154
+ return __awaiter(this, void 0, void 0, function* () {
155
+ const deployment = yield this._req(null, null, controllers.deploy.deployApp);
156
+ const prodAppId = deployment.appId.replace("_dev", "");
157
+ const appPackage = yield this._req(null, { appId: prodAppId }, controllers.app.fetchAppPackage);
158
+ return appPackage.application;
159
+ });
160
+ }
145
161
  updateTable(config = null) {
146
162
  return __awaiter(this, void 0, void 0, function* () {
147
163
  config = config || basicTable();
@@ -307,30 +323,29 @@ class TestConfiguration {
307
323
  return yield this._req(config, null, controllers.layout.save);
308
324
  });
309
325
  }
310
- createUser(id = null) {
326
+ createUser(id = null, email = EMAIL) {
311
327
  return __awaiter(this, void 0, void 0, function* () {
312
328
  const globalId = !id ? `us_${Math.random()}` : `us_${id}`;
313
- const resp = yield this.globalUser(globalId);
329
+ const resp = yield this.globalUser({ id: globalId, email });
314
330
  yield userCache.invalidateUser(globalId);
315
331
  return Object.assign(Object.assign({}, resp), { globalId });
316
332
  });
317
333
  }
318
- login(email, password, { roleId, userId, builder } = {}) {
334
+ login({ roleId, userId, builder, prodApp = false } = {}) {
319
335
  return __awaiter(this, void 0, void 0, function* () {
336
+ const appId = prodApp ? this.prodAppId : this.appId;
320
337
  userId = !userId ? `us_uuid1` : userId;
321
338
  if (!this.request) {
322
339
  throw "Server has not been opened, cannot login.";
323
340
  }
324
341
  // make sure the user exists in the global DB
325
342
  if (roleId !== BUILTIN_ROLE_IDS.PUBLIC) {
326
- const appId = `app${this.getAppId().split("app_dev")[1]}`;
327
- yield this.globalUser(userId, builder, {
328
- [appId]: roleId,
343
+ yield this.globalUser({
344
+ userId,
345
+ builder,
346
+ roles: { [this.prodAppId]: roleId },
329
347
  });
330
348
  }
331
- if (!email || !password) {
332
- yield this.createUser();
333
- }
334
349
  yield createASession(userId, {
335
350
  sessionId: "sessionid",
336
351
  tenantId: TENANT_ID,
@@ -343,7 +358,7 @@ class TestConfiguration {
343
358
  };
344
359
  const app = {
345
360
  roleId: roleId,
346
- appId: this.appId,
361
+ appId,
347
362
  };
348
363
  const authToken = jwt.sign(auth, env.JWT_SECRET);
349
364
  const appToken = jwt.sign(app, env.JWT_SECRET);
@@ -355,7 +370,7 @@ class TestConfiguration {
355
370
  `${Cookies.Auth}=${authToken}`,
356
371
  `${Cookies.CurrentApp}=${appToken}`,
357
372
  ],
358
- [Headers.APP_ID]: this.appId,
373
+ [Headers.APP_ID]: appId,
359
374
  };
360
375
  });
361
376
  }
@@ -13,4 +13,5 @@ module.exports = {
13
13
  screen: require("../../api/controllers/screen"),
14
14
  webhook: require("../../api/controllers/webhook"),
15
15
  layout: require("../../api/controllers/layout"),
16
+ deploy: require("../../api/controllers/deploy"),
16
17
  };