@budibase/server 0.9.169-alpha.9 → 0.9.172

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 (227) hide show
  1. package/builder/assets/{index.aafb155b.js → index.9ab01cd4.js} +34 -34
  2. package/builder/assets/{index.0ea76a5c.css → index.dbc6728e.css} +2 -2
  3. package/builder/assets/{vendor.2053eff2.js → vendor.54435e8f.js} +2 -2
  4. package/builder/index.html +3 -3
  5. package/coverage/clover.xml +517 -609
  6. package/coverage/coverage-final.json +31 -32
  7. package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
  8. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/application.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 +9 -6
  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 +17 -41
  17. package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/index.html +45 -45
  19. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/permission.js.html +4 -7
  23. package/coverage/lcov-report/api/controllers/query.js.html +24 -129
  24. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/index.html +5 -5
  28. package/coverage/lcov-report/api/controllers/row/index.js.html +15 -15
  29. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/script.js.html +57 -12
  34. package/coverage/lcov-report/api/controllers/table/index.html +28 -28
  35. package/coverage/lcov-report/api/controllers/table/index.js.html +37 -16
  36. package/coverage/lcov-report/api/controllers/table/utils.js.html +33 -279
  37. package/coverage/lcov-report/api/controllers/templates.js.html +13 -49
  38. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  41. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/view/utils.js.html +8 -8
  43. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +6 -6
  44. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  45. package/coverage/lcov-report/api/index.html +1 -1
  46. package/coverage/lcov-report/api/index.js.html +1 -1
  47. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  48. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/dev.js.html +11 -26
  58. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/index.html +9 -9
  60. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/metadata.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 +3 -9
  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/row.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/static.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/user.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 +10 -31
  78. package/coverage/lcov-report/automations/automationUtils.js.html +86 -14
  79. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  80. package/coverage/lcov-report/automations/index.html +25 -25
  81. package/coverage/lcov-report/automations/index.js.html +1 -1
  82. package/coverage/lcov-report/automations/steps/bash.js.html +7 -10
  83. package/coverage/lcov-report/automations/steps/createRow.js.html +2 -2
  84. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/deleteRow.js.html +5 -8
  86. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  87. package/coverage/lcov-report/automations/steps/executeQuery.js.html +7 -10
  88. package/coverage/lcov-report/automations/steps/executeScript.js.html +7 -10
  89. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/index.html +57 -57
  91. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +7 -10
  93. package/coverage/lcov-report/automations/steps/queryRows.js.html +7 -10
  94. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +7 -10
  95. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/updateRow.js.html +14 -14
  98. package/coverage/lcov-report/automations/steps/utils.js.html +10 -10
  99. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  100. package/coverage/lcov-report/automations/thread.js.html +12 -54
  101. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  102. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  108. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  109. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  110. package/coverage/lcov-report/automations/utils.js.html +1 -1
  111. package/coverage/lcov-report/constants/index.html +1 -1
  112. package/coverage/lcov-report/constants/index.js.html +2 -5
  113. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  114. package/coverage/lcov-report/constants/screens.js.html +1 -1
  115. package/coverage/lcov-report/db/client.js.html +1 -1
  116. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  117. package/coverage/lcov-report/db/index.html +1 -1
  118. package/coverage/lcov-report/db/index.js.html +1 -1
  119. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +12 -12
  120. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  121. package/coverage/lcov-report/db/linkedRows/index.js.html +9 -9
  122. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  123. package/coverage/lcov-report/db/newid.js.html +1 -1
  124. package/coverage/lcov-report/db/utils.js.html +1 -1
  125. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  126. package/coverage/lcov-report/events/index.html +1 -1
  127. package/coverage/lcov-report/events/index.js.html +1 -1
  128. package/coverage/lcov-report/events/utils.js.html +1 -1
  129. package/coverage/lcov-report/index.html +69 -69
  130. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  131. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  132. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  133. package/coverage/lcov-report/middleware/authorized.js.html +1 -1
  134. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  135. package/coverage/lcov-report/middleware/currentapp.js.html +2 -2
  136. package/coverage/lcov-report/middleware/index.html +1 -1
  137. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  138. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  139. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  140. package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
  141. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  142. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  143. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  144. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  145. package/coverage/lcov-report/utilities/global.js.html +2 -2
  146. package/coverage/lcov-report/utilities/index.html +7 -22
  147. package/coverage/lcov-report/utilities/index.js.html +1 -1
  148. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
  149. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  150. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  151. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  152. package/coverage/lcov-report/utilities/rowProcessor/index.html +14 -14
  153. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +8 -38
  154. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  155. package/coverage/lcov-report/utilities/security.js.html +1 -1
  156. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  157. package/coverage/lcov-report/utilities/users.js.html +1 -1
  158. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  159. package/coverage/lcov.info +848 -1026
  160. package/dist/api/controllers/backup.js +4 -4
  161. package/dist/api/controllers/dev.js +11 -17
  162. package/dist/api/controllers/permission.js +0 -1
  163. package/dist/api/controllers/query.js +8 -26
  164. package/dist/api/controllers/row/ExternalRequest.js +5 -46
  165. package/dist/api/controllers/script.js +16 -4
  166. package/dist/api/controllers/table/index.js +10 -5
  167. package/dist/api/controllers/table/utils.js +10 -83
  168. package/dist/api/controllers/templates.js +3 -18
  169. package/dist/api/routes/dev.js +4 -8
  170. package/dist/api/routes/query.js +1 -3
  171. package/dist/automations/actions.js +3 -9
  172. package/dist/automations/automationUtils.js +29 -8
  173. package/dist/automations/steps/bash.js +1 -2
  174. package/dist/automations/steps/createRow.js +1 -1
  175. package/dist/automations/steps/deleteRow.js +1 -2
  176. package/dist/automations/steps/executeQuery.js +1 -2
  177. package/dist/automations/steps/executeScript.js +1 -2
  178. package/dist/automations/steps/outgoingWebhook.js +1 -2
  179. package/dist/automations/steps/queryRows.js +1 -2
  180. package/dist/automations/steps/sendSmtpEmail.js +1 -2
  181. package/dist/automations/steps/updateRow.js +2 -6
  182. package/dist/automations/thread.js +3 -14
  183. package/dist/constants/index.js +0 -1
  184. package/dist/integrations/base/sql.js +4 -4
  185. package/dist/integrations/utils.js +1 -16
  186. package/dist/middleware/currentapp.js +1 -1
  187. package/dist/package.json +5 -6
  188. package/dist/tsconfig.tsbuildinfo +1 -1
  189. package/dist/utilities/fileSystem/index.js +33 -49
  190. package/dist/utilities/global.js +1 -1
  191. package/dist/utilities/rowProcessor/index.js +0 -8
  192. package/package.json +6 -7
  193. package/src/api/controllers/backup.js +5 -4
  194. package/src/api/controllers/dev.js +8 -16
  195. package/src/api/controllers/permission.js +0 -1
  196. package/src/api/controllers/query.js +11 -46
  197. package/src/api/controllers/row/ExternalRequest.ts +4 -49
  198. package/src/api/controllers/script.js +19 -4
  199. package/src/api/controllers/table/index.js +12 -5
  200. package/src/api/controllers/table/utils.js +12 -94
  201. package/src/api/controllers/templates.js +5 -17
  202. package/src/api/routes/dev.js +4 -9
  203. package/src/api/routes/query.js +1 -3
  204. package/src/automations/actions.js +3 -10
  205. package/src/automations/automationUtils.js +31 -7
  206. package/src/automations/steps/bash.js +1 -2
  207. package/src/automations/steps/createRow.js +1 -1
  208. package/src/automations/steps/deleteRow.js +1 -2
  209. package/src/automations/steps/executeQuery.js +1 -2
  210. package/src/automations/steps/executeScript.js +1 -2
  211. package/src/automations/steps/outgoingWebhook.js +1 -2
  212. package/src/automations/steps/queryRows.js +1 -2
  213. package/src/automations/steps/sendSmtpEmail.js +1 -2
  214. package/src/automations/steps/updateRow.js +6 -6
  215. package/src/automations/thread.js +3 -17
  216. package/src/constants/index.js +0 -1
  217. package/src/integrations/base/sql.ts +3 -5
  218. package/src/integrations/tests/mongo.spec.js +6 -10
  219. package/src/integrations/utils.ts +0 -15
  220. package/src/middleware/currentapp.js +1 -1
  221. package/src/middleware/tests/currentapp.spec.js +3 -3
  222. package/src/utilities/fileSystem/index.js +43 -65
  223. package/src/utilities/global.js +1 -1
  224. package/src/utilities/rowProcessor/index.js +0 -10
  225. package/coverage/lcov-report/utilities/scriptRunner.js.html +0 -143
  226. package/dist/utilities/scriptRunner.js +0 -19
  227. package/src/utilities/scriptRunner.js +0 -21
@@ -6,16 +6,11 @@ const { BUILDER } = require("@budibase/auth/permissions")
6
6
 
7
7
  const router = Router()
8
8
 
9
- function redirectPath(path) {
10
- router
11
- .get(`/api/${path}/:devPath(.*)`, controller.buildRedirectGet(path))
12
- .post(`/api/${path}/:devPath(.*)`, controller.buildRedirectPost(path))
13
- .delete(`/api/${path}/:devPath(.*)`, controller.buildRedirectDelete(path))
14
- }
15
-
16
9
  if (env.isDev() || env.isTest()) {
17
- redirectPath("global")
18
- redirectPath("system")
10
+ router
11
+ .get("/api/global/:devPath(.*)", controller.redirectGet)
12
+ .post("/api/global/:devPath(.*)", controller.redirectPost)
13
+ .delete("/api/global/:devPath(.*)", controller.redirectDelete)
19
14
  }
20
15
 
21
16
  router
@@ -31,8 +31,7 @@ function generateQueryValidation() {
31
31
  })),
32
32
  queryVerb: Joi.string().allow().required(),
33
33
  extra: Joi.object().optional(),
34
- schema: Joi.object({}).required().unknown(true),
35
- transformer: Joi.string().optional(),
34
+ schema: Joi.object({}).required().unknown(true)
36
35
  }))
37
36
  }
38
37
 
@@ -43,7 +42,6 @@ function generateQueryPreviewValidation() {
43
42
  queryVerb: Joi.string().allow().required(),
44
43
  extra: Joi.object().optional(),
45
44
  datasourceId: Joi.string().required(),
46
- transformer: Joi.string().optional(),
47
45
  parameters: Joi.object({}).required().unknown(true)
48
46
  }))
49
47
  }
@@ -3,6 +3,7 @@ const createRow = require("./steps/createRow")
3
3
  const updateRow = require("./steps/updateRow")
4
4
  const deleteRow = require("./steps/deleteRow")
5
5
  const executeScript = require("./steps/executeScript")
6
+ const bash = require("./steps/bash")
6
7
  const executeQuery = require("./steps/executeQuery")
7
8
  const outgoingWebhook = require("./steps/outgoingWebhook")
8
9
  const serverLog = require("./steps/serverLog")
@@ -13,7 +14,6 @@ const integromat = require("./steps/integromat")
13
14
  let filter = require("./steps/filter")
14
15
  let delay = require("./steps/delay")
15
16
  let queryRow = require("./steps/queryRows")
16
- const env = require("../environment")
17
17
 
18
18
  const ACTION_IMPLS = {
19
19
  SEND_EMAIL_SMTP: sendSmtpEmail.run,
@@ -22,6 +22,7 @@ const ACTION_IMPLS = {
22
22
  DELETE_ROW: deleteRow.run,
23
23
  OUTGOING_WEBHOOK: outgoingWebhook.run,
24
24
  EXECUTE_SCRIPT: executeScript.run,
25
+ EXECUTE_BASH: bash.run,
25
26
  EXECUTE_QUERY: executeQuery.run,
26
27
  SERVER_LOG: serverLog.run,
27
28
  DELAY: delay.run,
@@ -41,6 +42,7 @@ const ACTION_DEFINITIONS = {
41
42
  OUTGOING_WEBHOOK: outgoingWebhook.definition,
42
43
  EXECUTE_SCRIPT: executeScript.definition,
43
44
  EXECUTE_QUERY: executeQuery.definition,
45
+ EXECUTE_BASH: bash.definition,
44
46
  SERVER_LOG: serverLog.definition,
45
47
  DELAY: delay.definition,
46
48
  FILTER: filter.definition,
@@ -52,15 +54,6 @@ const ACTION_DEFINITIONS = {
52
54
  integromat: integromat.definition,
53
55
  }
54
56
 
55
- // don't add the bash script/definitions unless in self host
56
- // the fact this isn't included in any definitions means it cannot be
57
- // ran at all
58
- if (env.SELF_HOSTED) {
59
- const bash = require("./steps/bash")
60
- ACTION_IMPLS["EXECUTE_BASH"] = bash.run
61
- ACTION_DEFINITIONS["EXECUTE_BASH"] = bash.definition
62
- }
63
-
64
57
  /* istanbul ignore next */
65
58
  exports.getAction = async function (actionName) {
66
59
  if (ACTION_IMPLS[actionName] != null) {
@@ -1,4 +1,9 @@
1
- const { getTable } = require("../api/controllers/table/utils")
1
+ const CouchDB = require("../db")
2
+ const {
3
+ isExternalTable,
4
+ breakExternalTableId,
5
+ } = require("../integrations/utils")
6
+ const { getExternalTable } = require("../api/controllers/table/utils")
2
7
 
3
8
  /**
4
9
  * When values are input to the system generally they will be of type string as this is required for template strings.
@@ -16,7 +21,7 @@ const { getTable } = require("../api/controllers/table/utils")
16
21
  * @returns {object} The inputs object which has had all the various types supported by this function converted to their
17
22
  * primitive types.
18
23
  */
19
- exports.cleanInputValues = (inputs, schema) => {
24
+ module.exports.cleanInputValues = (inputs, schema) => {
20
25
  if (schema == null) {
21
26
  return inputs
22
27
  }
@@ -58,11 +63,30 @@ exports.cleanInputValues = (inputs, schema) => {
58
63
  * @param {object} row The input row structure which requires clean-up after having been through template statements.
59
64
  * @returns {Promise<Object>} The cleaned up rows object, will should now have all the required primitive types.
60
65
  */
61
- exports.cleanUpRow = async (appId, tableId, row) => {
62
- let table = await getTable(appId, tableId)
63
- return exports.cleanInputValues(row, { properties: table.schema })
66
+ module.exports.cleanUpRow = async (appId, tableId, row) => {
67
+ const db = new CouchDB(appId)
68
+ let table
69
+ if (isExternalTable(tableId)) {
70
+ const { datasourceId, tableName } = breakExternalTableId(tableId)
71
+ table = await getExternalTable(appId, datasourceId, tableName)
72
+ } else {
73
+ table = await db.get(tableId)
74
+ }
75
+
76
+ return module.exports.cleanInputValues(row, { properties: table.schema })
64
77
  }
65
78
 
66
- exports.getError = err => {
67
- return typeof err !== "string" ? err.toString() : err
79
+ /**
80
+ * A utility function for the cleanUpRow, which can be used if only the row ID is known (not the table ID) to clean
81
+ * up a row after template statements have been replaced. This is specifically useful for the update row action.
82
+ *
83
+ * @param {string} appId The instance which the Table/Table is contained under.
84
+ * @param {string} rowId The ID of the row from which the tableId will be extracted, to get the Table/Table schema.
85
+ * @param {object} row The input row structure which requires clean-up after having been through template statements.
86
+ * @returns {Promise<Object>} The cleaned up rows object, which will now have all the required primitive types.
87
+ */
88
+ module.exports.cleanUpRowById = async (appId, rowId, row) => {
89
+ const db = new CouchDB(appId)
90
+ const foundRow = await db.get(rowId)
91
+ return module.exports.cleanUpRow(appId, foundRow.tableId, row)
68
92
  }
@@ -1,6 +1,5 @@
1
1
  const { execSync } = require("child_process")
2
2
  const { processStringSync } = require("@budibase/string-templates")
3
- const automationUtils = require("../automationUtils")
4
3
 
5
4
  exports.definition = {
6
5
  name: "Bash Scripting",
@@ -64,7 +63,7 @@ exports.run = async function ({ inputs, context }) {
64
63
  } catch (err) {
65
64
  return {
66
65
  success: false,
67
- response: automationUtils.getError(err),
66
+ response: err,
68
67
  }
69
68
  }
70
69
  }
@@ -97,7 +97,7 @@ exports.run = async function ({ inputs, appId, emitter }) {
97
97
  } catch (err) {
98
98
  return {
99
99
  success: false,
100
- response: automationUtils.getError(err),
100
+ response: err,
101
101
  }
102
102
  }
103
103
  }
@@ -2,7 +2,6 @@ const rowController = require("../../api/controllers/row")
2
2
  const env = require("../../environment")
3
3
  const usage = require("../../utilities/usageQuota")
4
4
  const { buildCtx } = require("./utils")
5
- const automationUtils = require("../automationUtils")
6
5
 
7
6
  exports.definition = {
8
7
  description: "Delete a row from your database",
@@ -86,7 +85,7 @@ exports.run = async function ({ inputs, appId, emitter }) {
86
85
  } catch (err) {
87
86
  return {
88
87
  success: false,
89
- response: automationUtils.getError(err),
88
+ response: err,
90
89
  }
91
90
  }
92
91
  }
@@ -1,6 +1,5 @@
1
1
  const queryController = require("../../api/controllers/query")
2
2
  const { buildCtx } = require("./utils")
3
- const automationUtils = require("../automationUtils")
4
3
 
5
4
  exports.definition = {
6
5
  name: "External Data Connector",
@@ -75,7 +74,7 @@ exports.run = async function ({ inputs, appId, emitter }) {
75
74
  } catch (err) {
76
75
  return {
77
76
  success: false,
78
- response: automationUtils.getError(err),
77
+ response: err,
79
78
  }
80
79
  }
81
80
  }
@@ -1,6 +1,5 @@
1
1
  const scriptController = require("../../api/controllers/script")
2
2
  const { buildCtx } = require("./utils")
3
- const automationUtils = require("../automationUtils")
4
3
 
5
4
  exports.definition = {
6
5
  name: "JS Scripting",
@@ -64,7 +63,7 @@ exports.run = async function ({ inputs, appId, context, emitter }) {
64
63
  } catch (err) {
65
64
  return {
66
65
  success: false,
67
- response: automationUtils.getError(err),
66
+ response: err,
68
67
  }
69
68
  }
70
69
  }
@@ -1,6 +1,5 @@
1
1
  const fetch = require("node-fetch")
2
2
  const { getFetchResponse } = require("./utils")
3
- const automationUtils = require("../automationUtils")
4
3
 
5
4
  const RequestType = {
6
5
  POST: "POST",
@@ -128,7 +127,7 @@ exports.run = async function ({ inputs }) {
128
127
  /* istanbul ignore next */
129
128
  return {
130
129
  success: false,
131
- response: automationUtils.getError(err),
130
+ response: err,
132
131
  }
133
132
  }
134
133
  }
@@ -2,7 +2,6 @@ const rowController = require("../../api/controllers/row")
2
2
  const tableController = require("../../api/controllers/table")
3
3
  const { FieldTypes } = require("../../constants")
4
4
  const { buildCtx } = require("./utils")
5
- const automationUtils = require("../automationUtils")
6
5
 
7
6
  const SortOrders = {
8
7
  ASCENDING: "ascending",
@@ -111,7 +110,7 @@ exports.run = async function ({ inputs, appId }) {
111
110
  } catch (err) {
112
111
  return {
113
112
  success: false,
114
- response: automationUtils.getError(err),
113
+ response: err,
115
114
  }
116
115
  }
117
116
  }
@@ -1,5 +1,4 @@
1
1
  const { sendSmtpEmail } = require("../../utilities/workerRequests")
2
- const automationUtils = require("../automationUtils")
3
2
 
4
3
  exports.definition = {
5
4
  description: "Send an email using SMTP",
@@ -62,7 +61,7 @@ exports.run = async function ({ inputs }) {
62
61
  } catch (err) {
63
62
  return {
64
63
  success: false,
65
- response: automationUtils.getError(err),
64
+ response: err,
66
65
  }
67
66
  }
68
67
  }
@@ -64,7 +64,6 @@ exports.run = async function ({ inputs, appId, emitter }) {
64
64
  },
65
65
  }
66
66
  }
67
- const tableId = inputs.row.tableId
68
67
 
69
68
  // clear any falsy properties so that they aren't updated
70
69
  for (let propKey of Object.keys(inputs.row)) {
@@ -81,14 +80,15 @@ exports.run = async function ({ inputs, appId, emitter }) {
81
80
  },
82
81
  params: {
83
82
  rowId: inputs.rowId,
84
- tableId: tableId,
85
83
  },
86
84
  })
87
85
 
88
86
  try {
89
- if (tableId) {
90
- inputs.row = await automationUtils.cleanUpRow(appId, tableId, inputs.row)
91
- }
87
+ inputs.row = await automationUtils.cleanUpRowById(
88
+ appId,
89
+ inputs.rowId,
90
+ inputs.row
91
+ )
92
92
  await rowController.patch(ctx)
93
93
  return {
94
94
  row: ctx.body,
@@ -100,7 +100,7 @@ exports.run = async function ({ inputs, appId, emitter }) {
100
100
  } catch (err) {
101
101
  return {
102
102
  success: false,
103
- response: automationUtils.getError(err),
103
+ response: err,
104
104
  }
105
105
  }
106
106
  }
@@ -10,7 +10,6 @@ const env = require("../environment")
10
10
  const usage = require("../utilities/usageQuota")
11
11
 
12
12
  const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
13
- const STOPPED_STATUS = { success: false, status: "STOPPED" }
14
13
 
15
14
  /**
16
15
  * The automation orchestrator is a class responsible for executing automations.
@@ -69,13 +68,7 @@ class Orchestrator {
69
68
  async execute() {
70
69
  let automation = this._automation
71
70
  const app = await this.getApp()
72
- let stopped = false
73
71
  for (let step of automation.definition.steps) {
74
- // execution stopped, record state for that
75
- if (stopped) {
76
- this.updateExecutionOutput(step.id, step.stepId, {}, STOPPED_STATUS)
77
- continue
78
- }
79
72
  let stepFn = await this.getStepFunctionality(step.stepId)
80
73
  step.inputs = await processObject(step.inputs, this._context)
81
74
  step.inputs = automationUtils.cleanInputValues(
@@ -93,17 +86,10 @@ class Orchestrator {
93
86
  context: this._context,
94
87
  })
95
88
  })
96
- this._context.steps.push(outputs)
97
- // if filter causes us to stop execution don't break the loop, set a var
98
- // so that we can finish iterating through the steps and record that it stopped
99
89
  if (step.stepId === FILTER_STEP_ID && !outputs.success) {
100
- stopped = true
101
- this.updateExecutionOutput(step.id, step.stepId, step.inputs, {
102
- ...outputs,
103
- ...STOPPED_STATUS,
104
- })
105
- continue
90
+ break
106
91
  }
92
+ this._context.steps.push(outputs)
107
93
  this.updateExecutionOutput(step.id, step.stepId, step.inputs, outputs)
108
94
  } catch (err) {
109
95
  console.error(`Automation error - ${step.stepId} - ${err}`)
@@ -113,7 +99,7 @@ class Orchestrator {
113
99
 
114
100
  // Increment quota for automation runs
115
101
  if (!env.SELF_HOSTED && !isDevAppID(this._appId)) {
116
- await usage.update(usage.Properties.AUTOMATION, 1)
102
+ usage.update(usage.Properties.AUTOMATION, 1)
117
103
  }
118
104
  return this.executionOutput
119
105
  }
@@ -42,7 +42,6 @@ exports.FieldTypes = {
42
42
  FORMULA: "formula",
43
43
  AUTO: "auto",
44
44
  JSON: "json",
45
- INTERNAL: "internal",
46
45
  }
47
46
 
48
47
  exports.RelationshipTypes = {
@@ -98,9 +98,7 @@ function addFilters(
98
98
  }
99
99
 
100
100
  function addRelationships(
101
- knex: Knex,
102
101
  query: KnexQuery,
103
- fields: string | string[],
104
102
  fromTable: string,
105
103
  relationships: RelationshipsJson[] | undefined
106
104
  ): KnexQuery {
@@ -116,7 +114,7 @@ function addRelationships(
116
114
  query = query.leftJoin(
117
115
  toTable,
118
116
  `${fromTable}.${from}`,
119
- `${toTable}.${to}`
117
+ `${relationship.tableName}.${to}`
120
118
  )
121
119
  } else {
122
120
  const throughTable = relationship.through
@@ -132,7 +130,7 @@ function addRelationships(
132
130
  .leftJoin(toTable, `${toTable}.${toPrimary}`, `${throughTable}.${to}`)
133
131
  }
134
132
  }
135
- return query.limit(BASE_LIMIT)
133
+ return query
136
134
  }
137
135
 
138
136
  function buildCreate(
@@ -201,7 +199,7 @@ function buildRead(knex: Knex, json: QueryJson, limit: number): KnexQuery {
201
199
  [tableName]: query,
202
200
  }).select(selectStatement)
203
201
  // handle joins
204
- return addRelationships(knex, preQuery, selectStatement, tableName, relationships)
202
+ return addRelationships(preQuery, tableName, relationships)
205
203
  }
206
204
 
207
205
  function buildUpdate(
@@ -27,7 +27,7 @@ describe("MongoDB Integration", () => {
27
27
  const body = {
28
28
  name: "Hello"
29
29
  }
30
- await config.integration.create({
30
+ const response = await config.integration.create({
31
31
  index: indexName,
32
32
  json: body,
33
33
  extra: { collection: 'testCollection', actionTypes: 'insertOne'}
@@ -54,7 +54,7 @@ describe("MongoDB Integration", () => {
54
54
  },
55
55
  extra: { collection: 'testCollection', actionTypes: 'deleteOne'}
56
56
  }
57
- await config.integration.delete(query)
57
+ const response = await config.integration.delete(query)
58
58
  expect(config.integration.client.deleteOne).toHaveBeenCalledWith(query.json)
59
59
  })
60
60
 
@@ -65,7 +65,7 @@ describe("MongoDB Integration", () => {
65
65
  },
66
66
  extra: { collection: 'testCollection', actionTypes: 'updateOne'}
67
67
  }
68
- await config.integration.update(query)
68
+ const response = await config.integration.update(query)
69
69
  expect(config.integration.client.updateOne).toHaveBeenCalledWith(query.json)
70
70
  })
71
71
 
@@ -75,14 +75,10 @@ describe("MongoDB Integration", () => {
75
75
  const query = {
76
76
  extra: { collection: 'testCollection', actionTypes: 'deleteOne'}
77
77
  }
78
+ // Weird, need to do an IIFE for jest to recognize that it throws
79
+ expect(() => config.integration.read(query)()).toThrow(expect.any(Object))
78
80
 
79
- let error = null
80
- try {
81
- await config.integration.read(query)
82
- } catch (err) {
83
- error = err
84
- }
85
- expect(error).toBeDefined()
86
81
  restore()
87
82
  })
83
+
88
84
  })
@@ -5,7 +5,6 @@ const { DocumentTypes, SEPARATOR } = require("../db/utils")
5
5
  const { FieldTypes } = require("../constants")
6
6
 
7
7
  const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
8
- const ROW_ID_REGEX = /^\[.*]$/g
9
8
 
10
9
  export function isExternalTable(tableId: string) {
11
10
  return tableId.includes(DocumentTypes.DATASOURCE)
@@ -33,20 +32,6 @@ export function generateRowIdField(keyProps: any[] = []) {
33
32
  return encodeURIComponent(JSON.stringify(keyProps).replace(/"/g, "'"))
34
33
  }
35
34
 
36
- export function isRowId(field: any) {
37
- return Array.isArray(field) || (typeof field === "string" && field.match(ROW_ID_REGEX) != null)
38
- }
39
-
40
- export function convertRowId(field: any) {
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
-
50
35
  // should always return an array
51
36
  export function breakRowIdField(_id: string | { _id: string }): any[] {
52
37
  if (!_id) {
@@ -45,7 +45,7 @@ module.exports = async (ctx, next) => {
45
45
  const globalUser = await getCachedSelf(ctx, requestAppId)
46
46
  appId = requestAppId
47
47
  // retrieving global user gets the right role
48
- roleId = globalUser.roleId || roleId
48
+ roleId = globalUser.roleId || BUILTIN_ROLE_IDS.BASIC
49
49
  }
50
50
 
51
51
  // nothing more to do
@@ -127,8 +127,8 @@ describe("Current app middleware", () => {
127
127
  } else {
128
128
  expect(cookieFn).not.toHaveBeenCalled()
129
129
  }
130
- expect(config.ctx.roleId).toEqual("PUBLIC")
131
- expect(config.ctx.user.role._id).toEqual("PUBLIC")
130
+ expect(config.ctx.roleId).toEqual("BASIC")
131
+ expect(config.ctx.user.role._id).toEqual("BASIC")
132
132
  expect(config.ctx.appId).toEqual("app_test")
133
133
  expect(config.next).toHaveBeenCalled()
134
134
  }
@@ -163,7 +163,7 @@ describe("Current app middleware", () => {
163
163
  return "app_test"
164
164
  },
165
165
  setCookie: jest.fn(),
166
- getCookie: () => ({appId: "app_test", roleId: "PUBLIC"}),
166
+ getCookie: () => ({appId: "app_test", roleId: "BASIC"}),
167
167
  },
168
168
  constants: { Cookies: {} },
169
169
  }))
@@ -106,86 +106,64 @@ exports.apiFileReturn = contents => {
106
106
  }
107
107
 
108
108
  /**
109
- * Local utility to back up the database state for an app, excluding global user
110
- * data or user relationships.
111
- * @param {string} appId The app to backup
112
- * @param {object} config Config to send to export DB
113
- * @returns {*} either a string or a stream of the backup
109
+ * Takes a copy of the database state for an app to the object store.
110
+ * @param {string} appId The ID of the app which is to be backed up.
111
+ * @param {string} backupName The name of the backup located in the object store.
112
+ * @return The backup has been completed when this promise completes and returns a file stream
113
+ * to the temporary backup file (to return via API if required).
114
114
  */
115
- const backupAppData = async (appId, config) => {
116
- return await exports.exportDB(appId, {
117
- ...config,
115
+ exports.performBackup = async (appId, backupName) => {
116
+ return exports.exportDB(appId, {
117
+ exportName: backupName,
118
118
  filter: doc =>
119
119
  !(
120
120
  doc._id.includes(USER_METDATA_PREFIX) ||
121
- doc._id.includes(LINK_USER_METADATA_PREFIX)
121
+ doc.includes(LINK_USER_METADATA_PREFIX)
122
122
  ),
123
123
  })
124
124
  }
125
125
 
126
126
  /**
127
- * Takes a copy of the database state for an app to the object store.
128
- * @param {string} appId The ID of the app which is to be backed up.
129
- * @param {string} backupName The name of the backup located in the object store.
130
- * @return {*} a readable stream to the completed backup file
131
- */
132
- exports.performBackup = async (appId, backupName) => {
133
- return await backupAppData(appId, { exportName: backupName })
134
- }
135
-
136
- /**
137
- * Streams a backup of the database state for an app
138
- * @param {string} appId The ID of the app which is to be backed up.
139
- * @returns {*} a readable stream of the backup which is written in real time
140
- */
141
- exports.streamBackup = async appId => {
142
- return await backupAppData(appId, { stream: true })
143
- }
144
-
145
- /**
146
- * Exports a DB to either file or a variable (memory).
127
+ * exports a DB to either file or a variable (memory).
147
128
  * @param {string} dbName the DB which is to be exported.
148
- * @param {string} exportName optional - provide a filename to write the backup to a file
149
- * @param {boolean} stream optional - whether to perform a full backup
129
+ * @param {string} exportName optional - the file name to export to, if not in memory.
150
130
  * @param {function} filter optional - a filter function to clear out any un-wanted docs.
151
- * @return {*} either a readable stream or a string
131
+ * @return Either the file stream or the variable (if no export name provided).
152
132
  */
153
- exports.exportDB = async (dbName, { stream, filter, exportName } = {}) => {
154
- const instanceDb = new CouchDB(dbName)
155
-
156
- // Stream the dump if required
157
- if (stream) {
158
- const memStream = new MemoryStream()
159
- instanceDb.dump(memStream, { filter })
160
- return memStream
161
- }
162
-
163
- // Write the dump to file if required
133
+ exports.exportDB = async (
134
+ dbName,
135
+ { exportName, filter } = { exportName: undefined, filter: undefined }
136
+ ) => {
137
+ let stream,
138
+ appString = "",
139
+ path = null
164
140
  if (exportName) {
165
- const path = join(budibaseTempDir(), exportName)
166
- const writeStream = fs.createWriteStream(path)
167
- await instanceDb.dump(writeStream, { filter })
168
-
169
- // Upload the dump to the object store if self hosted
170
- if (env.SELF_HOSTED) {
171
- await streamUpload(
172
- ObjectStoreBuckets.BACKUPS,
173
- join(dbName, exportName),
174
- fs.createReadStream(path)
175
- )
176
- }
177
-
178
- return fs.createReadStream(path)
141
+ path = join(budibaseTempDir(), exportName)
142
+ stream = fs.createWriteStream(path)
143
+ } else {
144
+ stream = new MemoryStream()
145
+ stream.on("data", chunk => {
146
+ appString += chunk.toString()
147
+ })
179
148
  }
180
-
181
- // Stringify the dump in memory if required
182
- const memStream = new MemoryStream()
183
- let appString = ""
184
- memStream.on("data", chunk => {
185
- appString += chunk.toString()
149
+ // perform couch dump
150
+ const instanceDb = new CouchDB(dbName)
151
+ await instanceDb.dump(stream, {
152
+ filter,
186
153
  })
187
- await instanceDb.dump(memStream, { filter })
188
- return appString
154
+ // just in memory, return the final string
155
+ if (!exportName) {
156
+ return appString
157
+ }
158
+ // write the file to the object store
159
+ if (env.SELF_HOSTED) {
160
+ await streamUpload(
161
+ ObjectStoreBuckets.BACKUPS,
162
+ join(dbName, exportName),
163
+ fs.createReadStream(path)
164
+ )
165
+ }
166
+ return fs.createReadStream(path)
189
167
  }
190
168
 
191
169
  /**
@@ -26,7 +26,7 @@ exports.updateAppRole = (appId, user) => {
26
26
  if (!user.roleId && user.builder && user.builder.global) {
27
27
  user.roleId = BUILTIN_ROLE_IDS.ADMIN
28
28
  } else if (!user.roleId) {
29
- user.roleId = BUILTIN_ROLE_IDS.PUBLIC
29
+ user.roleId = BUILTIN_ROLE_IDS.BASIC
30
30
  }
31
31
  delete user.roles
32
32
  return user