@budibase/server 0.9.125-alpha.4 → 0.9.125-alpha.8

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 (270) hide show
  1. package/builder/assets/{index.dc48c234.js → index.cf133375.js} +2 -2
  2. package/builder/assets/{vendor.4af73c18.js → vendor.d8e1ee7b.js} +1 -1
  3. package/builder/index.html +2 -2
  4. package/coverage/clover.xml +1659 -1493
  5. package/coverage/coverage-final.json +101 -87
  6. package/coverage/lcov-report/api/controllers/analytics.js.html +3 -3
  7. package/coverage/lcov-report/api/controllers/apikeys.js.html +6 -6
  8. package/coverage/lcov-report/api/controllers/application.js.html +39 -39
  9. package/coverage/lcov-report/api/controllers/auth.js.html +6 -6
  10. package/coverage/lcov-report/api/controllers/automation.js.html +151 -361
  11. package/coverage/lcov-report/api/controllers/backup.js.html +3 -3
  12. package/coverage/lcov-report/api/controllers/component.js.html +5 -5
  13. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/dev.js.html +15 -15
  15. package/coverage/lcov-report/api/controllers/hosting.js.html +8 -8
  16. package/coverage/lcov-report/api/controllers/index.html +39 -24
  17. package/coverage/lcov-report/api/controllers/integration.js.html +4 -4
  18. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/metadata.js.html +218 -0
  20. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/query.js.html +6 -12
  22. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/routing.js.html +9 -9
  24. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/row/index.html +20 -20
  26. package/coverage/lcov-report/api/controllers/row/index.js.html +14 -14
  27. package/coverage/lcov-report/api/controllers/row/internal.js.html +95 -62
  28. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  29. package/coverage/lcov-report/api/controllers/row/utils.js.html +10 -10
  30. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  33. package/coverage/lcov-report/api/controllers/table/index.js.html +24 -24
  34. package/coverage/lcov-report/api/controllers/table/utils.js.html +32 -32
  35. package/coverage/lcov-report/api/controllers/templates.js.html +5 -5
  36. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  39. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  42. package/coverage/lcov-report/api/index.html +1 -1
  43. package/coverage/lcov-report/api/index.js.html +23 -23
  44. package/coverage/lcov-report/api/routes/analytics.js.html +6 -6
  45. package/coverage/lcov-report/api/routes/apikeys.js.html +8 -8
  46. package/coverage/lcov-report/api/routes/application.js.html +8 -8
  47. package/coverage/lcov-report/api/routes/auth.js.html +6 -6
  48. package/coverage/lcov-report/api/routes/automation.js.html +41 -26
  49. package/coverage/lcov-report/api/routes/backup.js.html +8 -8
  50. package/coverage/lcov-report/api/routes/component.js.html +8 -8
  51. package/coverage/lcov-report/api/routes/datasource.js.html +13 -13
  52. package/coverage/lcov-report/api/routes/deploy.js.html +8 -8
  53. package/coverage/lcov-report/api/routes/dev.js.html +11 -11
  54. package/coverage/lcov-report/api/routes/hosting.js.html +8 -8
  55. package/coverage/lcov-report/api/routes/index.html +24 -9
  56. package/coverage/lcov-report/api/routes/index.js.html +36 -30
  57. package/coverage/lcov-report/api/routes/integration.js.html +8 -8
  58. package/coverage/lcov-report/api/routes/layout.js.html +8 -8
  59. package/coverage/lcov-report/api/routes/metadata.js.html +194 -0
  60. package/coverage/lcov-report/api/routes/permission.js.html +12 -12
  61. package/coverage/lcov-report/api/routes/query.js.html +13 -13
  62. package/coverage/lcov-report/api/routes/role.js.html +12 -12
  63. package/coverage/lcov-report/api/routes/routing.js.html +8 -8
  64. package/coverage/lcov-report/api/routes/row.js.html +10 -10
  65. package/coverage/lcov-report/api/routes/screen.js.html +11 -11
  66. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/static.js.html +13 -13
  68. package/coverage/lcov-report/api/routes/table.js.html +12 -12
  69. package/coverage/lcov-report/api/routes/templates.js.html +8 -8
  70. package/coverage/lcov-report/api/routes/user.js.html +9 -9
  71. package/coverage/lcov-report/api/routes/view.js.html +11 -11
  72. package/coverage/lcov-report/api/routes/webhook.js.html +11 -11
  73. package/coverage/lcov-report/automations/actions.js.html +38 -107
  74. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  75. package/coverage/lcov-report/automations/bullboard.js.html +46 -16
  76. package/coverage/lcov-report/automations/index.html +67 -67
  77. package/coverage/lcov-report/automations/index.js.html +26 -128
  78. package/coverage/lcov-report/automations/steps/bash.js.html +33 -12
  79. package/coverage/lcov-report/automations/steps/createRow.js.html +8 -8
  80. package/coverage/lcov-report/automations/steps/delay.js.html +45 -6
  81. package/coverage/lcov-report/automations/steps/deleteRow.js.html +8 -8
  82. package/coverage/lcov-report/automations/steps/discord.js.html +329 -0
  83. package/coverage/lcov-report/automations/steps/executeQuery.js.html +19 -31
  84. package/coverage/lcov-report/automations/steps/executeScript.js.html +18 -30
  85. package/coverage/lcov-report/automations/steps/filter.js.html +22 -19
  86. package/coverage/lcov-report/automations/steps/index.html +125 -65
  87. package/coverage/lcov-report/automations/steps/integromat.js.html +341 -0
  88. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +26 -32
  89. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +9 -9
  90. package/coverage/lcov-report/automations/steps/serverLog.js.html +20 -8
  91. package/coverage/lcov-report/automations/steps/{sendgridEmail.js.html → slack.js.html} +57 -87
  92. package/coverage/lcov-report/automations/steps/updateRow.js.html +7 -7
  93. package/coverage/lcov-report/automations/steps/utils.js.html +188 -0
  94. package/coverage/lcov-report/automations/steps/zapier.js.html +332 -0
  95. package/coverage/lcov-report/automations/thread.js.html +79 -76
  96. package/coverage/lcov-report/automations/triggerInfo/app.js.html +173 -0
  97. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +173 -0
  98. package/coverage/lcov-report/automations/triggerInfo/index.html +201 -0
  99. package/coverage/lcov-report/automations/triggerInfo/index.js.html +125 -0
  100. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +176 -0
  101. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +200 -0
  102. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +200 -0
  103. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +188 -0
  104. package/coverage/lcov-report/automations/triggers.js.html +54 -819
  105. package/coverage/lcov-report/automations/utils.js.html +557 -0
  106. package/coverage/lcov-report/constants/index.html +5 -5
  107. package/coverage/lcov-report/constants/index.js.html +19 -4
  108. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  109. package/coverage/lcov-report/constants/screens.js.html +2 -2
  110. package/coverage/lcov-report/db/client.js.html +1 -1
  111. package/coverage/lcov-report/db/index.html +19 -19
  112. package/coverage/lcov-report/db/index.js.html +1 -1
  113. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +73 -73
  114. package/coverage/lcov-report/db/linkedRows/index.html +17 -17
  115. package/coverage/lcov-report/db/linkedRows/index.js.html +79 -115
  116. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +31 -31
  117. package/coverage/lcov-report/db/newid.js.html +2 -2
  118. package/coverage/lcov-report/db/utils.js.html +79 -28
  119. package/coverage/lcov-report/events/AutomationEmitter.js.html +7 -7
  120. package/coverage/lcov-report/events/index.html +1 -1
  121. package/coverage/lcov-report/events/index.js.html +2 -2
  122. package/coverage/lcov-report/events/utils.js.html +1 -1
  123. package/coverage/lcov-report/index.html +115 -100
  124. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  125. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  126. package/coverage/lcov-report/{automations/logic.js.html → middleware/appInfo.js.html} +35 -38
  127. package/coverage/lcov-report/middleware/authorized.js.html +16 -16
  128. package/coverage/lcov-report/middleware/builder.js.html +15 -15
  129. package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
  130. package/coverage/lcov-report/middleware/index.html +23 -8
  131. package/coverage/lcov-report/middleware/joi-validator.js.html +6 -6
  132. package/coverage/lcov-report/middleware/resourceId.js.html +28 -28
  133. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  134. package/coverage/lcov-report/middleware/usageQuota.js.html +8 -8
  135. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  136. package/coverage/lcov-report/utilities/budibaseDir.js.html +7 -7
  137. package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
  138. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  139. package/coverage/lcov-report/utilities/global.js.html +21 -21
  140. package/coverage/lcov-report/utilities/index.html +18 -18
  141. package/coverage/lcov-report/utilities/index.js.html +167 -14
  142. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +12 -12
  143. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  144. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  145. package/coverage/lcov-report/utilities/routing/index.js.html +6 -6
  146. package/coverage/lcov-report/utilities/rowProcessor/index.html +14 -14
  147. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +87 -51
  148. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +8 -8
  149. package/coverage/lcov-report/utilities/security.js.html +2 -2
  150. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  151. package/coverage/lcov-report/utilities/users.js.html +1 -1
  152. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  153. package/coverage/lcov.info +2641 -2357
  154. package/dist/api/controllers/automation.js +49 -127
  155. package/dist/api/controllers/deploy/index.js +17 -1
  156. package/dist/api/controllers/metadata.js +49 -0
  157. package/dist/api/controllers/query.js +0 -2
  158. package/dist/api/controllers/row/internal.js +33 -23
  159. package/dist/api/routes/automation.js +4 -5
  160. package/dist/api/routes/index.js +2 -0
  161. package/dist/api/routes/metadata.js +13 -0
  162. package/dist/api/routes/tests/utilities/TestFunctions.js +13 -0
  163. package/dist/app.js +1 -1
  164. package/dist/automations/actions.js +26 -46
  165. package/dist/automations/bullboard.js +10 -2
  166. package/dist/automations/index.js +11 -48
  167. package/dist/automations/steps/bash.js +11 -5
  168. package/dist/automations/steps/createRow.js +4 -4
  169. package/dist/automations/steps/delay.js +15 -2
  170. package/dist/automations/steps/deleteRow.js +4 -4
  171. package/dist/automations/steps/discord.js +91 -0
  172. package/dist/automations/steps/executeQuery.js +11 -14
  173. package/dist/automations/steps/executeScript.js +11 -14
  174. package/dist/automations/steps/filter.js +18 -17
  175. package/dist/automations/steps/integromat.js +94 -0
  176. package/dist/automations/steps/outgoingWebhook.js +12 -16
  177. package/dist/automations/steps/sendSmtpEmail.js +3 -3
  178. package/dist/automations/steps/serverLog.js +6 -2
  179. package/dist/automations/steps/slack.js +73 -0
  180. package/dist/automations/steps/updateRow.js +3 -3
  181. package/dist/automations/steps/utils.js +46 -0
  182. package/dist/automations/steps/zapier.js +91 -0
  183. package/dist/automations/tests/utilities/index.js +2 -12
  184. package/dist/automations/thread.js +23 -25
  185. package/dist/automations/triggerInfo/app.js +32 -0
  186. package/dist/automations/triggerInfo/cron.js +32 -0
  187. package/dist/automations/triggerInfo/index.js +15 -0
  188. package/dist/automations/triggerInfo/rowDeleted.js +33 -0
  189. package/dist/automations/triggerInfo/rowSaved.js +41 -0
  190. package/dist/automations/triggerInfo/rowUpdated.js +41 -0
  191. package/dist/automations/triggerInfo/webhook.js +37 -0
  192. package/dist/automations/triggers.js +27 -284
  193. package/dist/automations/utils.js +143 -0
  194. package/dist/constants/index.js +4 -0
  195. package/dist/db/linkedRows/index.js +14 -26
  196. package/dist/db/utils.js +14 -1
  197. package/dist/environment.js +1 -0
  198. package/dist/integrations/mysql.js +1 -1
  199. package/dist/middleware/appInfo.js +17 -0
  200. package/dist/middleware/usageQuota.js +1 -1
  201. package/dist/package.json +7 -6
  202. package/dist/tsconfig.tsbuildinfo +1 -1
  203. package/dist/utilities/fileSystem/index.js +0 -26
  204. package/dist/utilities/index.js +54 -0
  205. package/dist/utilities/redis.js +16 -1
  206. package/dist/utilities/rowProcessor/index.js +7 -4
  207. package/package.json +8 -7
  208. package/scripts/selfhost.js +8 -0
  209. package/src/api/controllers/automation.js +75 -145
  210. package/src/api/controllers/deploy/index.js +23 -1
  211. package/src/api/controllers/metadata.js +46 -0
  212. package/src/api/controllers/query.js +0 -2
  213. package/src/api/controllers/row/internal.js +34 -23
  214. package/src/api/routes/automation.js +16 -11
  215. package/src/api/routes/index.js +2 -0
  216. package/src/api/routes/metadata.js +38 -0
  217. package/src/api/routes/tests/automation.spec.js +4 -26
  218. package/src/api/routes/tests/metadata.spec.js +65 -0
  219. package/src/api/routes/tests/utilities/TestFunctions.js +14 -0
  220. package/src/app.ts +1 -1
  221. package/src/automations/actions.js +26 -49
  222. package/src/automations/bullboard.js +12 -2
  223. package/src/automations/index.js +11 -45
  224. package/src/automations/steps/bash.js +12 -5
  225. package/src/automations/steps/createRow.js +4 -4
  226. package/src/automations/steps/delay.js +15 -2
  227. package/src/automations/steps/deleteRow.js +4 -4
  228. package/src/automations/steps/discord.js +83 -0
  229. package/src/automations/steps/executeQuery.js +11 -15
  230. package/src/automations/steps/executeScript.js +11 -15
  231. package/src/automations/steps/filter.js +18 -17
  232. package/src/automations/steps/integromat.js +87 -0
  233. package/src/automations/steps/outgoingWebhook.js +12 -14
  234. package/src/automations/steps/sendSmtpEmail.js +3 -3
  235. package/src/automations/steps/serverLog.js +6 -2
  236. package/src/automations/steps/slack.js +64 -0
  237. package/src/automations/steps/updateRow.js +3 -3
  238. package/src/automations/steps/utils.js +36 -0
  239. package/src/automations/steps/zapier.js +84 -0
  240. package/src/automations/tests/automation.spec.js +3 -66
  241. package/src/automations/tests/delay.spec.js +1 -1
  242. package/src/automations/tests/filter.spec.js +13 -13
  243. package/src/automations/tests/utilities/index.js +2 -13
  244. package/src/automations/thread.js +27 -26
  245. package/src/automations/triggerInfo/app.js +31 -0
  246. package/src/automations/triggerInfo/cron.js +31 -0
  247. package/src/automations/triggerInfo/index.js +15 -0
  248. package/src/automations/triggerInfo/rowDeleted.js +32 -0
  249. package/src/automations/triggerInfo/rowSaved.js +40 -0
  250. package/src/automations/triggerInfo/rowUpdated.js +40 -0
  251. package/src/automations/triggerInfo/webhook.js +36 -0
  252. package/src/automations/triggers.js +33 -288
  253. package/src/automations/utils.js +159 -0
  254. package/src/constants/index.js +5 -0
  255. package/src/db/linkedRows/index.js +15 -27
  256. package/src/db/tests/linkTests.spec.js +0 -12
  257. package/src/db/utils.js +17 -0
  258. package/src/environment.js +1 -0
  259. package/src/integrations/mysql.ts +1 -1
  260. package/src/middleware/appInfo.js +19 -0
  261. package/src/middleware/usageQuota.js +1 -1
  262. package/src/utilities/fileSystem/index.js +0 -30
  263. package/src/utilities/index.js +51 -0
  264. package/src/utilities/redis.js +18 -1
  265. package/src/utilities/rowProcessor/index.js +16 -4
  266. package/dist/automations/logic.js +0 -17
  267. package/dist/automations/steps/sendgridEmail.js +0 -85
  268. package/src/automations/logic.js +0 -20
  269. package/src/automations/steps/sendgridEmail.js +0 -74
  270. package/src/automations/tests/sendEmail.spec.js +0 -36
@@ -0,0 +1,159 @@
1
+ const runner = require("./thread")
2
+ const { definitions } = require("./triggerInfo")
3
+ const webhooks = require("../api/controllers/webhook")
4
+ const CouchDB = require("../db")
5
+ const { queue } = require("./bullboard")
6
+ const newid = require("../db/newid")
7
+ const { updateEntityMetadata } = require("../utilities")
8
+ const { MetadataTypes } = require("../constants")
9
+
10
+ const WH_STEP_ID = definitions.WEBHOOK.stepId
11
+ const CRON_STEP_ID = definitions.CRON.stepId
12
+
13
+ exports.processEvent = async job => {
14
+ try {
15
+ // need to actually await these so that an error can be captured properly
16
+ return await runner(job)
17
+ } catch (err) {
18
+ console.error(
19
+ `${job.data.automation.appId} automation ${job.data.automation._id} was unable to run - ${err}`
20
+ )
21
+ return { err }
22
+ }
23
+ }
24
+
25
+ exports.updateTestHistory = async (appId, automation, history) => {
26
+ return updateEntityMetadata(
27
+ appId,
28
+ MetadataTypes.AUTOMATION_TEST_HISTORY,
29
+ automation._id,
30
+ metadata => {
31
+ if (metadata && Array.isArray(metadata.history)) {
32
+ metadata.history.push(history)
33
+ } else {
34
+ metadata = {
35
+ history: [history],
36
+ }
37
+ }
38
+ return metadata
39
+ }
40
+ )
41
+ }
42
+
43
+ // end the repetition and the job itself
44
+ exports.disableAllCrons = async appId => {
45
+ const promises = []
46
+ const jobs = await queue.getRepeatableJobs()
47
+ for (let job of jobs) {
48
+ if (job.key.includes(`${appId}_cron`)) {
49
+ promises.push(queue.removeRepeatableByKey(job.key))
50
+ promises.push(queue.removeJobs(job.id))
51
+ }
52
+ }
53
+ return Promise.all(promises)
54
+ }
55
+
56
+ /**
57
+ * This function handles checking of any cron jobs that need to be enabled/updated.
58
+ * @param {string} appId The ID of the app in which we are checking for webhooks
59
+ * @param {object|undefined} automation The automation object to be updated.
60
+ */
61
+ exports.enableCronTrigger = async (appId, automation) => {
62
+ const trigger = automation ? automation.definition.trigger : null
63
+ function isCronTrigger(auto) {
64
+ return (
65
+ auto &&
66
+ auto.definition.trigger &&
67
+ auto.definition.trigger.stepId === CRON_STEP_ID
68
+ )
69
+ }
70
+ // need to create cron job
71
+ if (isCronTrigger(automation)) {
72
+ // make a job id rather than letting Bull decide, makes it easier to handle on way out
73
+ const jobId = `${appId}_cron_${newid()}`
74
+ const job = await queue.add(
75
+ {
76
+ automation,
77
+ event: { appId, timestamp: Date.now() },
78
+ },
79
+ { repeat: { cron: trigger.inputs.cron }, jobId }
80
+ )
81
+ // Assign cron job ID from bull so we can remove it later if the cron trigger is removed
82
+ trigger.cronJobId = job.id
83
+ const db = new CouchDB(appId)
84
+ const response = await db.put(automation)
85
+ automation._id = response.id
86
+ automation._rev = response.rev
87
+ }
88
+ return automation
89
+ }
90
+
91
+ /**
92
+ * This function handles checking if any webhooks need to be created or deleted for automations.
93
+ * @param {string} appId The ID of the app in which we are checking for webhooks
94
+ * @param {object|undefined} oldAuto The old automation object if updating/deleting
95
+ * @param {object|undefined} newAuto The new automation object if creating/updating
96
+ * @returns {Promise<object|undefined>} After this is complete the new automation object may have been updated and should be
97
+ * written to DB (this does not write to DB as it would be wasteful to repeat).
98
+ */
99
+ exports.checkForWebhooks = async ({ appId, oldAuto, newAuto }) => {
100
+ const oldTrigger = oldAuto ? oldAuto.definition.trigger : null
101
+ const newTrigger = newAuto ? newAuto.definition.trigger : null
102
+ const triggerChanged =
103
+ oldTrigger && newTrigger && oldTrigger.id !== newTrigger.id
104
+ function isWebhookTrigger(auto) {
105
+ return (
106
+ auto &&
107
+ auto.definition.trigger &&
108
+ auto.definition.trigger.stepId === WH_STEP_ID
109
+ )
110
+ }
111
+ // need to delete webhook
112
+ if (
113
+ isWebhookTrigger(oldAuto) &&
114
+ (!isWebhookTrigger(newAuto) || triggerChanged) &&
115
+ oldTrigger.webhookId
116
+ ) {
117
+ try {
118
+ let db = new CouchDB(appId)
119
+ // need to get the webhook to get the rev
120
+ const webhook = await db.get(oldTrigger.webhookId)
121
+ const ctx = {
122
+ appId,
123
+ params: { id: webhook._id, rev: webhook._rev },
124
+ }
125
+ // might be updating - reset the inputs to remove the URLs
126
+ if (newTrigger) {
127
+ delete newTrigger.webhookId
128
+ newTrigger.inputs = {}
129
+ }
130
+ await webhooks.destroy(ctx)
131
+ } catch (err) {
132
+ // don't worry about not being able to delete, if it doesn't exist all good
133
+ }
134
+ }
135
+ // need to create webhook
136
+ if (
137
+ (!isWebhookTrigger(oldAuto) || triggerChanged) &&
138
+ isWebhookTrigger(newAuto)
139
+ ) {
140
+ const ctx = {
141
+ appId,
142
+ request: {
143
+ body: new webhooks.Webhook(
144
+ "Automation webhook",
145
+ webhooks.WebhookType.AUTOMATION,
146
+ newAuto._id
147
+ ),
148
+ },
149
+ }
150
+ await webhooks.save(ctx)
151
+ const id = ctx.body.webhook._id
152
+ newTrigger.webhookId = id
153
+ newTrigger.inputs = {
154
+ schemaUrl: `api/webhooks/schema/${appId}/${id}`,
155
+ triggerUrl: `api/webhooks/trigger/${appId}/${id}`,
156
+ }
157
+ }
158
+ return newAuto
159
+ }
@@ -123,5 +123,10 @@ exports.BaseQueryVerbs = {
123
123
  DELETE: "delete",
124
124
  }
125
125
 
126
+ exports.MetadataTypes = {
127
+ AUTOMATION_TEST_INPUT: "automationTestInput",
128
+ AUTOMATION_TEST_HISTORY: "automationTestHistory",
129
+ }
130
+
126
131
  // pass through the list from the auth/core lib
127
132
  exports.ObjectStoreBuckets = ObjectStoreBuckets
@@ -36,6 +36,18 @@ exports.IncludeDocs = IncludeDocs
36
36
  exports.getLinkDocuments = getLinkDocuments
37
37
  exports.createLinkView = createLinkView
38
38
 
39
+ function clearRelationshipFields(table, rows) {
40
+ for (let [key, field] of Object.entries(table.schema)) {
41
+ if (field.type === FieldTypes.LINK) {
42
+ rows = rows.map(row => {
43
+ delete row[key]
44
+ return row
45
+ })
46
+ }
47
+ }
48
+ return rows
49
+ }
50
+
39
51
  async function getLinksForRows(appId, rows) {
40
52
  const tableIds = [...new Set(rows.map(el => el.tableId))]
41
53
  // start by getting all the link values for performance reasons
@@ -126,33 +138,6 @@ exports.updateLinks = async function (args) {
126
138
  }
127
139
  }
128
140
 
129
- /**
130
- * Update a row with information about the links that pertain to it.
131
- * @param {string} appId The instance in which this row has been created.
132
- * @param {object} rows The row(s) themselves which is to be updated with info (if applicable). This can be
133
- * a single row object or an array of rows - both will be handled.
134
- * @returns {Promise<object>} The updated row (this may be the same if no links were found). If an array was input
135
- * then an array will be output, object input -> object output.
136
- */
137
- exports.attachLinkIDs = async (appId, rows) => {
138
- const links = await getLinksForRows(appId, rows)
139
- // now iterate through the rows and all field information
140
- for (let row of rows) {
141
- // find anything that matches the row's ID we are searching for and join it
142
- links
143
- .filter(el => el.thisId === row._id)
144
- .forEach(link => {
145
- if (row[link.fieldName] == null) {
146
- row[link.fieldName] = []
147
- }
148
- row[link.fieldName].push(link.id)
149
- })
150
- }
151
- // if it was an array when it came in then handle it as an array in response
152
- // otherwise return the first element as there was only one input
153
- return rows
154
- }
155
-
156
141
  /**
157
142
  * Given a table and a list of rows this will retrieve all of the attached docs and enrich them into the row.
158
143
  * This is required for formula fields, this may only be utilised internally (for now).
@@ -173,6 +158,9 @@ exports.attachFullLinkedDocs = async (ctx, table, rows) => {
173
158
  const links = (await getLinksForRows(appId, rows)).filter(link =>
174
159
  rows.some(row => row._id === link.thisId)
175
160
  )
161
+ // clear any existing links that could be dupe'd
162
+ rows = clearRelationshipFields(table, rows)
163
+ // now get the docs and combine into the rows
176
164
  let linked = await getFullLinkedDocs(ctx, appId, links)
177
165
  const linkedTables = []
178
166
  for (let row of rows) {
@@ -59,16 +59,4 @@ describe("test link functionality", () => {
59
59
  expect(Array.isArray(output)).toBe(true)
60
60
  })
61
61
  })
62
-
63
- describe("attachLinkIDs", () => {
64
- it("should be able to attach linkIDs", async () => {
65
- await config.init()
66
- await config.createTable()
67
- const table = await config.createLinkedTable()
68
- const row = await config.createRow()
69
- const linkRow = await config.createRow(basicLinkedRow(table._id, row._id))
70
- const attached = await links.attachLinkIDs(config.getAppId(), [linkRow])
71
- expect(attached[0].link[0]).toBe(row._id)
72
- })
73
- })
74
62
  })
package/src/db/utils.js CHANGED
@@ -7,6 +7,8 @@ const {
7
7
  APP_PREFIX,
8
8
  SEPARATOR,
9
9
  StaticDatabases,
10
+ isDevAppID,
11
+ isProdAppID,
10
12
  } = require("@budibase/auth/db")
11
13
 
12
14
  const UNICODE_MAX = "\ufff0"
@@ -36,6 +38,7 @@ const DocumentTypes = {
36
38
  DATASOURCE_PLUS: "datasource_plus",
37
39
  QUERY: "query",
38
40
  DEPLOYMENTS: "deployments",
41
+ METADATA: "metadata",
39
42
  }
40
43
 
41
44
  const ViewNames = {
@@ -63,6 +66,8 @@ const BudibaseInternalDB = {
63
66
 
64
67
  exports.APP_PREFIX = APP_PREFIX
65
68
  exports.APP_DEV_PREFIX = APP_DEV_PREFIX
69
+ exports.isDevAppID = isDevAppID
70
+ exports.isProdAppID = isProdAppID
66
71
  exports.USER_METDATA_PREFIX = `${DocumentTypes.ROW}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`
67
72
  exports.LINK_USER_METADATA_PREFIX = `${DocumentTypes.LINK}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`
68
73
  exports.ViewNames = ViewNames
@@ -331,6 +336,18 @@ exports.getQueryParams = (datasourceId = null, otherProps = {}) => {
331
336
  )
332
337
  }
333
338
 
339
+ exports.generateMetadataID = (type, entityId) => {
340
+ return `${DocumentTypes.METADATA}${SEPARATOR}${type}${SEPARATOR}${entityId}`
341
+ }
342
+
343
+ exports.getMetadataParams = (type, entityId = null, otherProps = {}) => {
344
+ let docId = `${type}${SEPARATOR}`
345
+ if (entityId != null) {
346
+ docId += entityId
347
+ }
348
+ return getDocParams(DocumentTypes.METADATA, docId, otherProps)
349
+ }
350
+
334
351
  /**
335
352
  * This can be used with the db.allDocs to get a list of IDs
336
353
  */
@@ -55,6 +55,7 @@ module.exports = {
55
55
  BUDIBASE_API_KEY: process.env.BUDIBASE_API_KEY,
56
56
  USERID_API_KEY: process.env.USERID_API_KEY,
57
57
  DEPLOYMENT_CREDENTIALS_URL: process.env.DEPLOYMENT_CREDENTIALS_URL,
58
+ ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS,
58
59
  _set(key, value) {
59
60
  process.env[key] = value
60
61
  module.exports[key] = value
@@ -152,7 +152,7 @@ module MySQLModule {
152
152
  false
153
153
  )
154
154
  const tableNames = tablesResp.map(
155
- (obj: any) => obj[`Tables_in_${database}`]
155
+ (obj: any) => obj[`Tables_in_${database.toLowerCase()}`]
156
156
  )
157
157
  for (let tableName of tableNames) {
158
158
  const primaryKeys = []
@@ -0,0 +1,19 @@
1
+ const { isDevAppID, isProdAppID } = require("../db/utils")
2
+
3
+ exports.AppType = {
4
+ DEV: "dev",
5
+ PROD: "prod",
6
+ }
7
+
8
+ exports.middleware =
9
+ ({ appType } = {}) =>
10
+ (ctx, next) => {
11
+ const appId = ctx.appId
12
+ if (appType === exports.AppType.DEV && appId && !isDevAppID(appId)) {
13
+ ctx.throw(400, "Only apps in development support this endpoint")
14
+ }
15
+ if (appType === exports.AppType.PROD && appId && !isProdAppID(appId)) {
16
+ ctx.throw(400, "Only apps in production support this endpoint")
17
+ }
18
+ return next()
19
+ }
@@ -14,7 +14,7 @@ const DOMAIN_MAP = {
14
14
  views: usageQuota.Properties.VIEW,
15
15
  users: usageQuota.Properties.USER,
16
16
  // this will not be updated by endpoint calls
17
- // instead it will be updated by triggers
17
+ // instead it will be updated by triggerInfo
18
18
  automationRuns: usageQuota.Properties.AUTOMATION,
19
19
  }
20
20
 
@@ -14,18 +14,12 @@ const {
14
14
  downloadTarball,
15
15
  } = require("./utilities")
16
16
  const { updateClientLibrary } = require("./clientLibrary")
17
- const download = require("download")
18
17
  const env = require("../../environment")
19
- const { homedir } = require("os")
20
- const fetch = require("node-fetch")
21
18
  const {
22
19
  USER_METDATA_PREFIX,
23
20
  LINK_USER_METADATA_PREFIX,
24
21
  } = require("../../db/utils")
25
22
 
26
- const DEFAULT_AUTOMATION_BUCKET =
27
- "https://prod-budi-automations.s3-eu-west-1.amazonaws.com"
28
- const DEFAULT_AUTOMATION_DIRECTORY = ".budibase-automations"
29
23
  const TOP_LEVEL_PATH = join(__dirname, "..", "..", "..")
30
24
  const NODE_MODULES_PATH = join(TOP_LEVEL_PATH, "node_modules")
31
25
 
@@ -205,30 +199,6 @@ exports.getComponentLibraryManifest = async (appId, library) => {
205
199
  return JSON.parse(resp)
206
200
  }
207
201
 
208
- exports.automationInit = async () => {
209
- const directory =
210
- env.AUTOMATION_DIRECTORY || join(homedir(), DEFAULT_AUTOMATION_DIRECTORY)
211
- const bucket = env.AUTOMATION_BUCKET || DEFAULT_AUTOMATION_BUCKET
212
- if (!fs.existsSync(directory)) {
213
- fs.mkdirSync(directory, { recursive: true })
214
- }
215
- // env setup to get async packages
216
- let response = await fetch(`${bucket}/manifest.json`)
217
- return response.json()
218
- }
219
-
220
- exports.getExternalAutomationStep = async (name, version, bundleName) => {
221
- const directory =
222
- env.AUTOMATION_DIRECTORY || join(homedir(), DEFAULT_AUTOMATION_DIRECTORY)
223
- const bucket = env.AUTOMATION_BUCKET || DEFAULT_AUTOMATION_BUCKET
224
- try {
225
- return require(join(directory, bundleName))
226
- } catch (err) {
227
- await download(`${bucket}/${name}/${version}/${bundleName}`, directory)
228
- return require(join(directory, bundleName))
229
- }
230
- }
231
-
232
202
  /**
233
203
  * All file reads come through here just to make sure all of them make sense
234
204
  * allows a centralised location to check logic is all good.
@@ -1,6 +1,8 @@
1
1
  const env = require("../environment")
2
2
  const { OBJ_STORE_DIRECTORY } = require("../constants")
3
3
  const { sanitizeKey } = require("@budibase/auth/src/objectStore")
4
+ const CouchDB = require("../db")
5
+ const { generateMetadataID } = require("../db/utils")
4
6
 
5
7
  const BB_CDN = "https://cdn.budi.live"
6
8
 
@@ -55,3 +57,52 @@ exports.attachmentsRelativeURL = attachmentKey => {
55
57
  `${exports.objectStoreUrl()}/${attachmentKey}`
56
58
  )
57
59
  }
60
+
61
+ exports.updateEntityMetadata = async (appId, type, entityId, updateFn) => {
62
+ const db = new CouchDB(appId)
63
+ const id = generateMetadataID(type, entityId)
64
+ // read it to see if it exists, we'll overwrite it no matter what
65
+ let rev,
66
+ metadata = {}
67
+ try {
68
+ const oldMetadata = await db.get(id)
69
+ rev = oldMetadata._rev
70
+ metadata = updateFn(oldMetadata)
71
+ } catch (err) {
72
+ rev = null
73
+ metadata = updateFn({})
74
+ }
75
+ metadata._id = id
76
+ if (rev) {
77
+ metadata._rev = rev
78
+ }
79
+ const response = await db.put(metadata)
80
+ return {
81
+ ...metadata,
82
+ _id: id,
83
+ _rev: response.rev,
84
+ }
85
+ }
86
+
87
+ exports.saveEntityMetadata = async (appId, type, entityId, metadata) => {
88
+ return exports.updateEntityMetadata(appId, type, entityId, () => {
89
+ return metadata
90
+ })
91
+ }
92
+
93
+ exports.deleteEntityMetadata = async (appId, type, entityId) => {
94
+ const db = new CouchDB(appId)
95
+ const id = generateMetadataID(type, entityId)
96
+ let rev
97
+ try {
98
+ const metadata = await db.get(id)
99
+ if (metadata) {
100
+ rev = metadata._rev
101
+ }
102
+ } catch (err) {
103
+ // don't need to error if it doesn't exist
104
+ }
105
+ if (id && rev) {
106
+ await db.remove(id, rev)
107
+ }
108
+ }