@budibase/server 0.9.136 → 0.9.140-alpha.0

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 (296) hide show
  1. package/builder/assets/discord.c14881e9.svg +10 -0
  2. package/builder/assets/{index.a0ab7774.js → index.0d1fa670.js} +35 -35
  3. package/builder/assets/{index.121692c9.css → index.79907e5c.css} +5 -5
  4. package/builder/assets/integromat.42212f11.png +0 -0
  5. package/builder/assets/slack.1e1f7cfb.svg +33 -0
  6. package/builder/assets/{vendor.7177f366.js → vendor.d39b3c1e.js} +2 -2
  7. package/builder/assets/zapier.3fbd8f5c.png +0 -0
  8. package/builder/index.html +3 -3
  9. package/coverage/clover.xml +2142 -2095
  10. package/coverage/coverage-final.json +120 -106
  11. package/coverage/lcov-report/api/controllers/analytics.js.html +3 -3
  12. package/coverage/lcov-report/api/controllers/apikeys.js.html +6 -6
  13. package/coverage/lcov-report/api/controllers/application.js.html +84 -84
  14. package/coverage/lcov-report/api/controllers/auth.js.html +6 -6
  15. package/coverage/lcov-report/api/controllers/automation.js.html +182 -356
  16. package/coverage/lcov-report/api/controllers/backup.js.html +3 -3
  17. package/coverage/lcov-report/api/controllers/component.js.html +5 -5
  18. package/coverage/lcov-report/api/controllers/datasource.js.html +12 -12
  19. package/coverage/lcov-report/api/controllers/dev.js.html +15 -15
  20. package/coverage/lcov-report/api/controllers/hosting.js.html +8 -8
  21. package/coverage/lcov-report/api/controllers/index.html +47 -32
  22. package/coverage/lcov-report/api/controllers/integration.js.html +4 -4
  23. package/coverage/lcov-report/api/controllers/layout.js.html +6 -6
  24. package/coverage/lcov-report/api/controllers/metadata.js.html +218 -0
  25. package/coverage/lcov-report/api/controllers/permission.js.html +14 -14
  26. package/coverage/lcov-report/api/controllers/query.js.html +17 -23
  27. package/coverage/lcov-report/api/controllers/role.js.html +9 -9
  28. package/coverage/lcov-report/api/controllers/routing.js.html +9 -9
  29. package/coverage/lcov-report/api/controllers/row/external.js.html +15 -15
  30. package/coverage/lcov-report/api/controllers/row/index.html +29 -44
  31. package/coverage/lcov-report/api/controllers/row/index.js.html +48 -45
  32. package/coverage/lcov-report/api/controllers/row/internal.js.html +159 -126
  33. package/coverage/lcov-report/api/controllers/row/utils.js.html +17 -17
  34. package/coverage/lcov-report/api/controllers/screen.js.html +7 -7
  35. package/coverage/lcov-report/api/controllers/script.js.html +5 -5
  36. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  37. package/coverage/lcov-report/api/controllers/table/index.js.html +40 -40
  38. package/coverage/lcov-report/api/controllers/table/utils.js.html +48 -48
  39. package/coverage/lcov-report/api/controllers/templates.js.html +5 -5
  40. package/coverage/lcov-report/api/controllers/user.js.html +14 -11
  41. package/coverage/lcov-report/api/controllers/view/exporters.js.html +3 -3
  42. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  43. package/coverage/lcov-report/api/controllers/view/index.js.html +9 -9
  44. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +6 -6
  45. package/coverage/lcov-report/api/controllers/webhook.js.html +14 -14
  46. package/coverage/lcov-report/api/index.html +1 -1
  47. package/coverage/lcov-report/api/index.js.html +23 -23
  48. package/coverage/lcov-report/api/routes/analytics.js.html +6 -6
  49. package/coverage/lcov-report/api/routes/apikeys.js.html +8 -8
  50. package/coverage/lcov-report/api/routes/application.js.html +8 -8
  51. package/coverage/lcov-report/api/routes/auth.js.html +6 -6
  52. package/coverage/lcov-report/api/routes/automation.js.html +41 -26
  53. package/coverage/lcov-report/api/routes/backup.js.html +8 -8
  54. package/coverage/lcov-report/api/routes/component.js.html +8 -8
  55. package/coverage/lcov-report/api/routes/datasource.js.html +13 -13
  56. package/coverage/lcov-report/api/routes/deploy.js.html +8 -8
  57. package/coverage/lcov-report/api/routes/dev.js.html +11 -11
  58. package/coverage/lcov-report/api/routes/hosting.js.html +8 -8
  59. package/coverage/lcov-report/api/routes/index.html +24 -9
  60. package/coverage/lcov-report/api/routes/index.js.html +36 -30
  61. package/coverage/lcov-report/api/routes/integration.js.html +8 -8
  62. package/coverage/lcov-report/api/routes/layout.js.html +8 -8
  63. package/coverage/lcov-report/api/routes/metadata.js.html +194 -0
  64. package/coverage/lcov-report/api/routes/permission.js.html +12 -12
  65. package/coverage/lcov-report/api/routes/query.js.html +13 -13
  66. package/coverage/lcov-report/api/routes/role.js.html +12 -12
  67. package/coverage/lcov-report/api/routes/routing.js.html +8 -8
  68. package/coverage/lcov-report/api/routes/row.js.html +10 -10
  69. package/coverage/lcov-report/api/routes/screen.js.html +11 -11
  70. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/static.js.html +13 -16
  72. package/coverage/lcov-report/api/routes/table.js.html +12 -12
  73. package/coverage/lcov-report/api/routes/templates.js.html +8 -8
  74. package/coverage/lcov-report/api/routes/user.js.html +9 -9
  75. package/coverage/lcov-report/api/routes/view.js.html +11 -11
  76. package/coverage/lcov-report/api/routes/webhook.js.html +11 -11
  77. package/coverage/lcov-report/automations/actions.js.html +57 -117
  78. package/coverage/lcov-report/automations/automationUtils.js.html +7 -7
  79. package/coverage/lcov-report/automations/bullboard.js.html +49 -16
  80. package/coverage/lcov-report/automations/index.html +67 -67
  81. package/coverage/lcov-report/automations/index.js.html +27 -129
  82. package/coverage/lcov-report/automations/steps/bash.js.html +37 -16
  83. package/coverage/lcov-report/automations/steps/createRow.js.html +15 -15
  84. package/coverage/lcov-report/automations/steps/delay.js.html +48 -9
  85. package/coverage/lcov-report/automations/steps/deleteRow.js.html +14 -14
  86. package/coverage/lcov-report/automations/steps/discord.js.html +329 -0
  87. package/coverage/lcov-report/automations/steps/executeQuery.js.html +22 -34
  88. package/coverage/lcov-report/automations/steps/executeScript.js.html +21 -33
  89. package/coverage/lcov-report/automations/steps/filter.js.html +28 -25
  90. package/coverage/lcov-report/automations/steps/index.html +140 -65
  91. package/coverage/lcov-report/automations/steps/integromat.js.html +341 -0
  92. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +44 -38
  93. package/coverage/lcov-report/automations/steps/queryRows.js.html +437 -0
  94. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +13 -13
  95. package/coverage/lcov-report/automations/steps/serverLog.js.html +23 -11
  96. package/coverage/lcov-report/automations/steps/{sendgridEmail.js.html → slack.js.html} +58 -88
  97. package/coverage/lcov-report/automations/steps/updateRow.js.html +12 -12
  98. package/coverage/lcov-report/automations/steps/utils.js.html +188 -0
  99. package/coverage/lcov-report/automations/steps/zapier.js.html +332 -0
  100. package/coverage/lcov-report/automations/thread.js.html +81 -78
  101. package/coverage/lcov-report/automations/triggerInfo/app.js.html +173 -0
  102. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +173 -0
  103. package/coverage/lcov-report/automations/triggerInfo/index.html +201 -0
  104. package/coverage/lcov-report/automations/triggerInfo/index.js.html +125 -0
  105. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +176 -0
  106. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +200 -0
  107. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +200 -0
  108. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +188 -0
  109. package/coverage/lcov-report/automations/triggers.js.html +67 -838
  110. package/coverage/lcov-report/automations/utils.js.html +557 -0
  111. package/coverage/lcov-report/constants/index.html +5 -5
  112. package/coverage/lcov-report/constants/index.js.html +32 -17
  113. package/coverage/lcov-report/constants/layouts.js.html +5 -5
  114. package/coverage/lcov-report/constants/screens.js.html +4 -4
  115. package/coverage/lcov-report/db/client.js.html +18 -18
  116. package/coverage/lcov-report/db/index.html +19 -19
  117. package/coverage/lcov-report/db/index.js.html +3 -3
  118. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +79 -79
  119. package/coverage/lcov-report/db/linkedRows/index.html +18 -18
  120. package/coverage/lcov-report/db/linkedRows/index.js.html +107 -149
  121. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +43 -43
  122. package/coverage/lcov-report/db/newid.js.html +4 -4
  123. package/coverage/lcov-report/db/utils.js.html +127 -76
  124. package/coverage/lcov-report/events/AutomationEmitter.js.html +7 -7
  125. package/coverage/lcov-report/events/index.html +1 -1
  126. package/coverage/lcov-report/events/index.js.html +6 -6
  127. package/coverage/lcov-report/events/utils.js.html +3 -3
  128. package/coverage/lcov-report/index.html +116 -101
  129. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  130. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  131. package/coverage/lcov-report/{automations/logic.js.html → middleware/appInfo.js.html} +35 -38
  132. package/coverage/lcov-report/middleware/authorized.js.html +16 -16
  133. package/coverage/lcov-report/middleware/builder.js.html +15 -15
  134. package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
  135. package/coverage/lcov-report/middleware/index.html +23 -8
  136. package/coverage/lcov-report/middleware/joi-validator.js.html +6 -6
  137. package/coverage/lcov-report/middleware/resourceId.js.html +28 -28
  138. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  139. package/coverage/lcov-report/middleware/usageQuota.js.html +8 -8
  140. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  141. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  142. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  143. package/coverage/lcov-report/utilities/csvParser.js.html +6 -6
  144. package/coverage/lcov-report/utilities/global.js.html +33 -33
  145. package/coverage/lcov-report/utilities/index.html +28 -28
  146. package/coverage/lcov-report/utilities/index.js.html +178 -25
  147. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +18 -18
  148. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  149. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  150. package/coverage/lcov-report/utilities/routing/index.js.html +6 -6
  151. package/coverage/lcov-report/utilities/rowProcessor/index.html +14 -14
  152. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +87 -51
  153. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +10 -10
  154. package/coverage/lcov-report/utilities/security.js.html +9 -9
  155. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  156. package/coverage/lcov-report/utilities/users.js.html +5 -5
  157. package/coverage/lcov-report/utilities/workerRequests.js.html +52 -52
  158. package/coverage/lcov.info +3250 -3213
  159. package/dist/api/controllers/automation.js +60 -127
  160. package/dist/api/controllers/deploy/index.js +17 -1
  161. package/dist/api/controllers/metadata.js +49 -0
  162. package/dist/api/controllers/query.js +0 -2
  163. package/dist/api/controllers/row/ExternalRequest.js +1 -1
  164. package/dist/api/controllers/row/index.js +1 -0
  165. package/dist/api/controllers/row/internal.js +33 -23
  166. package/dist/api/controllers/static/index.js +1 -28
  167. package/dist/api/controllers/static/templates/BudibaseApp.svelte +4 -1
  168. package/dist/api/controllers/user.js +1 -1
  169. package/dist/api/routes/automation.js +4 -5
  170. package/dist/api/routes/index.js +2 -0
  171. package/dist/api/routes/metadata.js +13 -0
  172. package/dist/api/routes/static.js +0 -1
  173. package/dist/api/routes/tests/utilities/TestFunctions.js +13 -0
  174. package/dist/app.js +1 -1
  175. package/dist/automations/actions.js +29 -46
  176. package/dist/automations/bullboard.js +11 -2
  177. package/dist/automations/index.js +11 -48
  178. package/dist/automations/steps/bash.js +12 -6
  179. package/dist/automations/steps/createRow.js +5 -5
  180. package/dist/automations/steps/delay.js +16 -3
  181. package/dist/automations/steps/deleteRow.js +5 -5
  182. package/dist/automations/steps/discord.js +91 -0
  183. package/dist/automations/steps/executeQuery.js +12 -15
  184. package/dist/automations/steps/executeScript.js +12 -15
  185. package/dist/automations/steps/filter.js +19 -18
  186. package/dist/automations/steps/integromat.js +94 -0
  187. package/dist/automations/steps/outgoingWebhook.js +19 -20
  188. package/dist/automations/steps/queryRows.js +129 -0
  189. package/dist/automations/steps/sendSmtpEmail.js +4 -4
  190. package/dist/automations/steps/serverLog.js +7 -3
  191. package/dist/automations/steps/slack.js +73 -0
  192. package/dist/automations/steps/updateRow.js +4 -4
  193. package/dist/automations/steps/utils.js +46 -0
  194. package/dist/automations/steps/zapier.js +91 -0
  195. package/dist/automations/tests/utilities/index.js +2 -12
  196. package/dist/automations/thread.js +23 -25
  197. package/dist/automations/triggerInfo/app.js +32 -0
  198. package/dist/automations/triggerInfo/cron.js +32 -0
  199. package/dist/automations/triggerInfo/index.js +15 -0
  200. package/dist/automations/triggerInfo/rowDeleted.js +33 -0
  201. package/dist/automations/triggerInfo/rowSaved.js +41 -0
  202. package/dist/automations/triggerInfo/rowUpdated.js +41 -0
  203. package/dist/automations/triggerInfo/webhook.js +37 -0
  204. package/dist/automations/triggers.js +27 -285
  205. package/dist/automations/utils.js +143 -0
  206. package/dist/constants/index.js +4 -0
  207. package/dist/db/linkedRows/index.js +20 -34
  208. package/dist/db/utils.js +14 -1
  209. package/dist/environment.js +2 -1
  210. package/dist/integrations/mysql.js +14 -2
  211. package/dist/middleware/appInfo.js +17 -0
  212. package/dist/middleware/usageQuota.js +1 -1
  213. package/dist/package.json +12 -11
  214. package/dist/tsconfig.tsbuildinfo +1 -1
  215. package/dist/utilities/appDirectoryTemplate/package.json +1 -1
  216. package/dist/utilities/fileSystem/clientLibrary.js +2 -2
  217. package/dist/utilities/fileSystem/index.js +2 -27
  218. package/dist/utilities/index.js +54 -0
  219. package/dist/utilities/redis.js +16 -1
  220. package/dist/utilities/rowProcessor/index.js +7 -4
  221. package/package.json +13 -12
  222. package/scripts/jestSetup.js +1 -0
  223. package/scripts/selfhost.js +8 -0
  224. package/src/api/controllers/automation.js +87 -145
  225. package/src/api/controllers/deploy/index.js +23 -1
  226. package/src/api/controllers/metadata.js +46 -0
  227. package/src/api/controllers/query.js +0 -2
  228. package/src/api/controllers/row/ExternalRequest.ts +1 -1
  229. package/src/api/controllers/row/index.js +1 -0
  230. package/src/api/controllers/row/internal.js +34 -23
  231. package/src/api/controllers/static/index.js +1 -39
  232. package/src/api/controllers/static/templates/BudibaseApp.svelte +4 -1
  233. package/src/api/controllers/user.js +1 -0
  234. package/src/api/routes/automation.js +16 -11
  235. package/src/api/routes/index.js +2 -0
  236. package/src/api/routes/metadata.js +38 -0
  237. package/src/api/routes/static.js +0 -1
  238. package/src/api/routes/tests/automation.spec.js +4 -26
  239. package/src/api/routes/tests/metadata.spec.js +65 -0
  240. package/src/api/routes/tests/utilities/TestFunctions.js +14 -0
  241. package/src/app.ts +1 -1
  242. package/src/automations/actions.js +29 -49
  243. package/src/automations/bullboard.js +13 -2
  244. package/src/automations/index.js +11 -45
  245. package/src/automations/steps/bash.js +13 -6
  246. package/src/automations/steps/createRow.js +5 -5
  247. package/src/automations/steps/delay.js +16 -3
  248. package/src/automations/steps/deleteRow.js +5 -5
  249. package/src/automations/steps/discord.js +83 -0
  250. package/src/automations/steps/executeQuery.js +12 -16
  251. package/src/automations/steps/executeScript.js +12 -16
  252. package/src/automations/steps/filter.js +19 -18
  253. package/src/automations/steps/integromat.js +87 -0
  254. package/src/automations/steps/outgoingWebhook.js +20 -18
  255. package/src/automations/steps/queryRows.js +119 -0
  256. package/src/automations/steps/sendSmtpEmail.js +4 -4
  257. package/src/automations/steps/serverLog.js +7 -3
  258. package/src/automations/steps/slack.js +64 -0
  259. package/src/automations/steps/updateRow.js +4 -4
  260. package/src/automations/steps/utils.js +36 -0
  261. package/src/automations/steps/zapier.js +84 -0
  262. package/src/automations/tests/automation.spec.js +4 -67
  263. package/src/automations/tests/delay.spec.js +2 -2
  264. package/src/automations/tests/filter.spec.js +14 -14
  265. package/src/automations/tests/queryRows.spec.js +51 -0
  266. package/src/automations/tests/utilities/index.js +2 -13
  267. package/src/automations/thread.js +27 -26
  268. package/src/automations/triggerInfo/app.js +31 -0
  269. package/src/automations/triggerInfo/cron.js +31 -0
  270. package/src/automations/triggerInfo/index.js +15 -0
  271. package/src/automations/triggerInfo/rowDeleted.js +32 -0
  272. package/src/automations/triggerInfo/rowSaved.js +40 -0
  273. package/src/automations/triggerInfo/rowUpdated.js +40 -0
  274. package/src/automations/triggerInfo/webhook.js +36 -0
  275. package/src/automations/triggers.js +33 -290
  276. package/src/automations/utils.js +159 -0
  277. package/src/constants/index.js +5 -0
  278. package/src/db/linkedRows/index.js +21 -35
  279. package/src/db/tests/linkTests.spec.js +0 -12
  280. package/src/db/utils.js +17 -0
  281. package/src/environment.js +2 -1
  282. package/src/integrations/mysql.ts +15 -2
  283. package/src/middleware/appInfo.js +19 -0
  284. package/src/middleware/usageQuota.js +1 -1
  285. package/src/utilities/appDirectoryTemplate/package.json +1 -1
  286. package/src/utilities/fileSystem/clientLibrary.js +2 -2
  287. package/src/utilities/fileSystem/index.js +2 -36
  288. package/src/utilities/index.js +51 -0
  289. package/src/utilities/redis.js +18 -1
  290. package/src/utilities/rowProcessor/index.js +16 -4
  291. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +0 -1244
  292. package/dist/automations/logic.js +0 -17
  293. package/dist/automations/steps/sendgridEmail.js +0 -85
  294. package/src/automations/logic.js +0 -20
  295. package/src/automations/steps/sendgridEmail.js +0 -74
  296. package/src/automations/tests/sendEmail.spec.js +0 -36
@@ -10,235 +10,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  const CouchDB = require("../db");
12
12
  const emitter = require("../events/index");
13
- const env = require("../environment");
14
- const Queue = env.isTest()
15
- ? require("../utilities/queue/inMemoryQueue")
16
- : require("bull");
17
13
  const { getAutomationParams } = require("../db/utils");
18
14
  const { coerce } = require("../utilities/rowProcessor");
19
- const { utils } = require("@budibase/auth/redis");
20
- const { JobQueues } = require("../constants");
21
- const { isExternalTable, breakExternalTableId, } = require("../integrations/utils");
22
- const { getExternalTable } = require("../api/controllers/table/utils");
23
- const { opts, redisProtocolUrl } = utils.getRedisOptions();
24
- const redisConfig = redisProtocolUrl || { redis: opts };
25
- let automationQueue = new Queue(JobQueues.AUTOMATIONS, redisConfig);
26
- const FAKE_STRING = "TEST";
27
- const FAKE_BOOL = false;
28
- const FAKE_NUMBER = 1;
29
- const FAKE_DATETIME = "1970-01-01T00:00:00.000Z";
30
- const BUILTIN_DEFINITIONS = {
31
- ROW_SAVED: {
32
- name: "Row Created",
33
- event: "row:save",
34
- icon: "ri-save-line",
35
- tagline: "Row is added to {{inputs.enriched.table.name}}",
36
- description: "Fired when a row is added to your database",
37
- stepId: "ROW_SAVED",
38
- inputs: {},
39
- schema: {
40
- inputs: {
41
- properties: {
42
- tableId: {
43
- type: "string",
44
- customType: "table",
45
- title: "Table",
46
- },
47
- },
48
- required: ["tableId"],
49
- },
50
- outputs: {
51
- properties: {
52
- row: {
53
- type: "object",
54
- customType: "row",
55
- description: "The new row that was created",
56
- },
57
- id: {
58
- type: "string",
59
- description: "Row ID - can be used for updating",
60
- },
61
- revision: {
62
- type: "string",
63
- description: "Revision of row",
64
- },
65
- },
66
- required: ["row", "id"],
67
- },
68
- },
69
- type: "TRIGGER",
70
- },
71
- ROW_UPDATED: {
72
- name: "Row Updated",
73
- event: "row:update",
74
- icon: "ri-refresh-line",
75
- tagline: "Row is updated in {{inputs.enriched.table.name}}",
76
- description: "Fired when a row is updated in your database",
77
- stepId: "ROW_UPDATED",
78
- inputs: {},
79
- schema: {
80
- inputs: {
81
- properties: {
82
- tableId: {
83
- type: "string",
84
- customType: "table",
85
- title: "Table",
86
- },
87
- },
88
- required: ["tableId"],
89
- },
90
- outputs: {
91
- properties: {
92
- row: {
93
- type: "object",
94
- customType: "row",
95
- description: "The row that was updated",
96
- },
97
- id: {
98
- type: "string",
99
- description: "Row ID - can be used for updating",
100
- },
101
- revision: {
102
- type: "string",
103
- description: "Revision of row",
104
- },
105
- },
106
- required: ["row", "id"],
107
- },
108
- },
109
- type: "TRIGGER",
110
- },
111
- ROW_DELETED: {
112
- name: "Row Deleted",
113
- event: "row:delete",
114
- icon: "ri-delete-bin-line",
115
- tagline: "Row is deleted from {{inputs.enriched.table.name}}",
116
- description: "Fired when a row is deleted from your database",
117
- stepId: "ROW_DELETED",
118
- inputs: {},
119
- schema: {
120
- inputs: {
121
- properties: {
122
- tableId: {
123
- type: "string",
124
- customType: "table",
125
- title: "Table",
126
- },
127
- },
128
- required: ["tableId"],
129
- },
130
- outputs: {
131
- properties: {
132
- row: {
133
- type: "object",
134
- customType: "row",
135
- description: "The row that was deleted",
136
- },
137
- },
138
- required: ["row"],
139
- },
140
- },
141
- type: "TRIGGER",
142
- },
143
- WEBHOOK: {
144
- name: "Webhook",
145
- event: "web:trigger",
146
- icon: "ri-global-line",
147
- tagline: "Webhook endpoint is hit",
148
- description: "Trigger an automation when a HTTP POST webhook is hit",
149
- stepId: "WEBHOOK",
150
- inputs: {},
151
- schema: {
152
- inputs: {
153
- properties: {
154
- schemaUrl: {
155
- type: "string",
156
- customType: "webhookUrl",
157
- title: "Schema URL",
158
- },
159
- triggerUrl: {
160
- type: "string",
161
- customType: "webhookUrl",
162
- title: "Trigger URL",
163
- },
164
- },
165
- required: ["schemaUrl", "triggerUrl"],
166
- },
167
- outputs: {
168
- properties: {
169
- body: {
170
- type: "object",
171
- description: "Body of the request which hit the webhook",
172
- },
173
- },
174
- required: ["body"],
175
- },
176
- },
177
- type: "TRIGGER",
178
- },
179
- APP: {
180
- name: "App Action",
181
- event: "app:trigger",
182
- icon: "ri-window-fill",
183
- tagline: "Automation fired from the frontend",
184
- description: "Trigger an automation from an action inside your app",
185
- stepId: "APP",
186
- inputs: {},
187
- schema: {
188
- inputs: {
189
- properties: {
190
- fields: {
191
- type: "object",
192
- customType: "triggerSchema",
193
- title: "Fields",
194
- },
195
- },
196
- required: [],
197
- },
198
- outputs: {
199
- properties: {
200
- fields: {
201
- type: "object",
202
- description: "Fields submitted from the app frontend",
203
- },
204
- },
205
- required: ["fields"],
206
- },
207
- },
208
- type: "TRIGGER",
209
- },
210
- CRON: {
211
- name: "Cron Trigger",
212
- event: "cron:trigger",
213
- icon: "ri-timer-line",
214
- tagline: "Cron Trigger (<b>{{inputs.cron}}</b>)",
215
- description: "Triggers automation on a cron schedule.",
216
- stepId: "CRON",
217
- inputs: {},
218
- schema: {
219
- inputs: {
220
- properties: {
221
- cron: {
222
- type: "string",
223
- customType: "cron",
224
- title: "Expression",
225
- },
226
- },
227
- required: ["cron"],
228
- },
229
- outputs: {
230
- properties: {
231
- timestamp: {
232
- type: "number",
233
- description: "Timestamp the cron was executed",
234
- },
235
- },
236
- required: ["timestamp"],
237
- },
238
- },
239
- type: "TRIGGER",
240
- },
241
- };
15
+ const { definitions } = require("./triggerInfo");
16
+ const { isDevAppID } = require("../db/utils");
17
+ // need this to call directly, so we can get a response
18
+ const { queue } = require("./bullboard");
19
+ const { checkTestFlag } = require("../utilities/redis");
20
+ const utils = require("./utils");
21
+ const env = require("../environment");
22
+ const TRIGGER_DEFINITIONS = definitions;
242
23
  function queueRelevantRowAutomations(event, eventType) {
243
24
  return __awaiter(this, void 0, void 0, function* () {
244
25
  if (event.appId == null) {
@@ -256,12 +37,18 @@ function queueRelevantRowAutomations(event, eventType) {
256
37
  for (let automation of automations) {
257
38
  let automationDef = automation.definition;
258
39
  let automationTrigger = automationDef ? automationDef.trigger : {};
259
- if (!automation.live ||
260
- !automationTrigger.inputs ||
261
- automationTrigger.inputs.tableId !== event.row.tableId) {
40
+ // don't queue events which are for dev apps, only way to test automations is
41
+ // running tests on them, in production the test flag will never
42
+ // be checked due to lazy evaluation (first always false)
43
+ if (!env.ALLOW_DEV_AUTOMATIONS &&
44
+ isDevAppID(event.appId) &&
45
+ !(yield checkTestFlag(automation._id))) {
262
46
  continue;
263
47
  }
264
- automationQueue.add({ automation, event });
48
+ if (automationTrigger.inputs &&
49
+ automationTrigger.inputs.tableId === event.row.tableId) {
50
+ yield queue.add({ automation, event });
51
+ }
265
52
  }
266
53
  });
267
54
  }
@@ -292,55 +79,9 @@ emitter.on("row:delete", function (event) {
292
79
  yield queueRelevantRowAutomations(event, "row:delete");
293
80
  });
294
81
  });
295
- function fillRowOutput(automation, params) {
82
+ exports.externalTrigger = function (automation, params, { getResponses } = {}) {
296
83
  return __awaiter(this, void 0, void 0, function* () {
297
- let triggerSchema = automation.definition.trigger;
298
- let tableId = triggerSchema.inputs.tableId;
299
- try {
300
- let table;
301
- if (!isExternalTable(tableId)) {
302
- const db = new CouchDB(params.appId);
303
- table = yield db.get(tableId);
304
- }
305
- else {
306
- const { datasourceId, tableName } = breakExternalTableId(tableId);
307
- table = yield getExternalTable(params.appId, datasourceId, tableName);
308
- }
309
- let row = {};
310
- for (let schemaKey of Object.keys(table.schema)) {
311
- const paramValue = params[schemaKey];
312
- let propSchema = table.schema[schemaKey];
313
- switch (propSchema.constraints.type) {
314
- case "string":
315
- row[schemaKey] = paramValue || FAKE_STRING;
316
- break;
317
- case "boolean":
318
- row[schemaKey] = paramValue || FAKE_BOOL;
319
- break;
320
- case "number":
321
- row[schemaKey] = paramValue || FAKE_NUMBER;
322
- break;
323
- case "datetime":
324
- row[schemaKey] = paramValue || FAKE_DATETIME;
325
- break;
326
- }
327
- }
328
- params.row = row;
329
- }
330
- catch (err) {
331
- /* istanbul ignore next */
332
- throw "Failed to find table for trigger";
333
- }
334
- return params;
335
- });
336
- }
337
- module.exports.externalTrigger = function (automation, params) {
338
- return __awaiter(this, void 0, void 0, function* () {
339
- // TODO: replace this with allowing user in builder to input values in future
340
84
  if (automation.definition != null && automation.definition.trigger != null) {
341
- if (automation.definition.trigger.inputs.tableId != null) {
342
- params = yield fillRowOutput(automation, params);
343
- }
344
85
  if (automation.definition.trigger.stepId === "APP") {
345
86
  // values are likely to be submitted as strings, so we shall convert to correct type
346
87
  const coercedFields = {};
@@ -351,12 +92,13 @@ module.exports.externalTrigger = function (automation, params) {
351
92
  params.fields = coercedFields;
352
93
  }
353
94
  }
354
- automationQueue.add({ automation, event: params });
95
+ const data = { automation, event: params };
96
+ if (getResponses) {
97
+ return utils.processEvent({ data });
98
+ }
99
+ else {
100
+ return queue.add(data);
101
+ }
355
102
  });
356
103
  };
357
- module.exports.getQueues = () => {
358
- return [automationQueue];
359
- };
360
- module.exports.fillRowOutput = fillRowOutput;
361
- module.exports.automationQueue = automationQueue;
362
- module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS;
104
+ exports.TRIGGER_DEFINITIONS = TRIGGER_DEFINITIONS;
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ const runner = require("./thread");
12
+ const { definitions } = require("./triggerInfo");
13
+ const webhooks = require("../api/controllers/webhook");
14
+ const CouchDB = require("../db");
15
+ const { queue } = require("./bullboard");
16
+ const newid = require("../db/newid");
17
+ const { updateEntityMetadata } = require("../utilities");
18
+ const { MetadataTypes } = require("../constants");
19
+ const WH_STEP_ID = definitions.WEBHOOK.stepId;
20
+ const CRON_STEP_ID = definitions.CRON.stepId;
21
+ exports.processEvent = (job) => __awaiter(void 0, void 0, void 0, function* () {
22
+ try {
23
+ // need to actually await these so that an error can be captured properly
24
+ return yield runner(job);
25
+ }
26
+ catch (err) {
27
+ console.error(`${job.data.automation.appId} automation ${job.data.automation._id} was unable to run - ${err}`);
28
+ return { err };
29
+ }
30
+ });
31
+ exports.updateTestHistory = (appId, automation, history) => __awaiter(void 0, void 0, void 0, function* () {
32
+ return updateEntityMetadata(appId, MetadataTypes.AUTOMATION_TEST_HISTORY, automation._id, metadata => {
33
+ if (metadata && Array.isArray(metadata.history)) {
34
+ metadata.history.push(history);
35
+ }
36
+ else {
37
+ metadata = {
38
+ history: [history],
39
+ };
40
+ }
41
+ return metadata;
42
+ });
43
+ });
44
+ // end the repetition and the job itself
45
+ exports.disableAllCrons = (appId) => __awaiter(void 0, void 0, void 0, function* () {
46
+ const promises = [];
47
+ const jobs = yield queue.getRepeatableJobs();
48
+ for (let job of jobs) {
49
+ if (job.key.includes(`${appId}_cron`)) {
50
+ promises.push(queue.removeRepeatableByKey(job.key));
51
+ promises.push(queue.removeJobs(job.id));
52
+ }
53
+ }
54
+ return Promise.all(promises);
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 = (appId, automation) => __awaiter(void 0, void 0, void 0, function* () {
62
+ const trigger = automation ? automation.definition.trigger : null;
63
+ function isCronTrigger(auto) {
64
+ return (auto &&
65
+ auto.definition.trigger &&
66
+ auto.definition.trigger.stepId === CRON_STEP_ID);
67
+ }
68
+ // need to create cron job
69
+ if (isCronTrigger(automation)) {
70
+ // make a job id rather than letting Bull decide, makes it easier to handle on way out
71
+ const jobId = `${appId}_cron_${newid()}`;
72
+ const job = yield queue.add({
73
+ automation,
74
+ event: { appId, timestamp: Date.now() },
75
+ }, { repeat: { cron: trigger.inputs.cron }, jobId });
76
+ // Assign cron job ID from bull so we can remove it later if the cron trigger is removed
77
+ trigger.cronJobId = job.id;
78
+ const db = new CouchDB(appId);
79
+ const response = yield db.put(automation);
80
+ automation._id = response.id;
81
+ automation._rev = response.rev;
82
+ }
83
+ return automation;
84
+ });
85
+ /**
86
+ * This function handles checking if any webhooks need to be created or deleted for automations.
87
+ * @param {string} appId The ID of the app in which we are checking for webhooks
88
+ * @param {object|undefined} oldAuto The old automation object if updating/deleting
89
+ * @param {object|undefined} newAuto The new automation object if creating/updating
90
+ * @returns {Promise<object|undefined>} After this is complete the new automation object may have been updated and should be
91
+ * written to DB (this does not write to DB as it would be wasteful to repeat).
92
+ */
93
+ exports.checkForWebhooks = ({ appId, oldAuto, newAuto }) => __awaiter(void 0, void 0, void 0, function* () {
94
+ const oldTrigger = oldAuto ? oldAuto.definition.trigger : null;
95
+ const newTrigger = newAuto ? newAuto.definition.trigger : null;
96
+ const triggerChanged = oldTrigger && newTrigger && oldTrigger.id !== newTrigger.id;
97
+ function isWebhookTrigger(auto) {
98
+ return (auto &&
99
+ auto.definition.trigger &&
100
+ auto.definition.trigger.stepId === WH_STEP_ID);
101
+ }
102
+ // need to delete webhook
103
+ if (isWebhookTrigger(oldAuto) &&
104
+ (!isWebhookTrigger(newAuto) || triggerChanged) &&
105
+ oldTrigger.webhookId) {
106
+ try {
107
+ let db = new CouchDB(appId);
108
+ // need to get the webhook to get the rev
109
+ const webhook = yield db.get(oldTrigger.webhookId);
110
+ const ctx = {
111
+ appId,
112
+ params: { id: webhook._id, rev: webhook._rev },
113
+ };
114
+ // might be updating - reset the inputs to remove the URLs
115
+ if (newTrigger) {
116
+ delete newTrigger.webhookId;
117
+ newTrigger.inputs = {};
118
+ }
119
+ yield webhooks.destroy(ctx);
120
+ }
121
+ catch (err) {
122
+ // don't worry about not being able to delete, if it doesn't exist all good
123
+ }
124
+ }
125
+ // need to create webhook
126
+ if ((!isWebhookTrigger(oldAuto) || triggerChanged) &&
127
+ isWebhookTrigger(newAuto)) {
128
+ const ctx = {
129
+ appId,
130
+ request: {
131
+ body: new webhooks.Webhook("Automation webhook", webhooks.WebhookType.AUTOMATION, newAuto._id),
132
+ },
133
+ };
134
+ yield webhooks.save(ctx);
135
+ const id = ctx.body.webhook._id;
136
+ newTrigger.webhookId = id;
137
+ newTrigger.inputs = {
138
+ schemaUrl: `api/webhooks/schema/${appId}/${id}`,
139
+ triggerUrl: `api/webhooks/trigger/${appId}/${id}`,
140
+ };
141
+ }
142
+ return newAuto;
143
+ });
@@ -114,5 +114,9 @@ exports.BaseQueryVerbs = {
114
114
  UPDATE: "update",
115
115
  DELETE: "delete",
116
116
  };
117
+ exports.MetadataTypes = {
118
+ AUTOMATION_TEST_INPUT: "automationTestInput",
119
+ AUTOMATION_TEST_HISTORY: "automationTestHistory",
120
+ };
117
121
  // pass through the list from the auth/core lib
118
122
  exports.ObjectStoreBuckets = ObjectStoreBuckets;
@@ -34,6 +34,17 @@ exports.EventType = EventType;
34
34
  exports.IncludeDocs = IncludeDocs;
35
35
  exports.getLinkDocuments = getLinkDocuments;
36
36
  exports.createLinkView = createLinkView;
37
+ function clearRelationshipFields(table, rows) {
38
+ for (let [key, field] of Object.entries(table.schema)) {
39
+ if (field.type === FieldTypes.LINK) {
40
+ rows = rows.map(row => {
41
+ delete row[key];
42
+ return row;
43
+ });
44
+ }
45
+ }
46
+ return rows;
47
+ }
37
48
  function getLinksForRows(appId, rows) {
38
49
  return __awaiter(this, void 0, void 0, function* () {
39
50
  const tableIds = [...new Set(rows.map(el => el.tableId))];
@@ -113,32 +124,6 @@ exports.updateLinks = function (args) {
113
124
  }
114
125
  });
115
126
  };
116
- /**
117
- * Update a row with information about the links that pertain to it.
118
- * @param {string} appId The instance in which this row has been created.
119
- * @param {object} rows The row(s) themselves which is to be updated with info (if applicable). This can be
120
- * a single row object or an array of rows - both will be handled.
121
- * @returns {Promise<object>} The updated row (this may be the same if no links were found). If an array was input
122
- * then an array will be output, object input -> object output.
123
- */
124
- exports.attachLinkIDs = (appId, rows) => __awaiter(void 0, void 0, void 0, function* () {
125
- const links = yield getLinksForRows(appId, rows);
126
- // now iterate through the rows and all field information
127
- for (let row of rows) {
128
- // find anything that matches the row's ID we are searching for and join it
129
- links
130
- .filter(el => el.thisId === row._id)
131
- .forEach(link => {
132
- if (row[link.fieldName] == null) {
133
- row[link.fieldName] = [];
134
- }
135
- row[link.fieldName].push(link.id);
136
- });
137
- }
138
- // if it was an array when it came in then handle it as an array in response
139
- // otherwise return the first element as there was only one input
140
- return rows;
141
- });
142
127
  /**
143
128
  * Given a table and a list of rows this will retrieve all of the attached docs and enrich them into the row.
144
129
  * This is required for formula fields, this may only be utilised internally (for now).
@@ -157,6 +142,9 @@ exports.attachFullLinkedDocs = (ctx, table, rows) => __awaiter(void 0, void 0, v
157
142
  const db = new CouchDB(appId);
158
143
  // get all the links
159
144
  const links = (yield getLinksForRows(appId, rows)).filter(link => rows.some(row => row._id === link.thisId));
145
+ // clear any existing links that could be dupe'd
146
+ rows = clearRelationshipFields(table, rows);
147
+ // now get the docs and combine into the rows
160
148
  let linked = yield getFullLinkedDocs(ctx, appId, links);
161
149
  const linkedTables = [];
162
150
  for (let row of rows) {
@@ -185,19 +173,17 @@ exports.attachFullLinkedDocs = (ctx, table, rows) => __awaiter(void 0, void 0, v
185
173
  exports.squashLinksToPrimaryDisplay = (appId, table, enriched) => __awaiter(void 0, void 0, void 0, function* () {
186
174
  const db = new CouchDB(appId);
187
175
  // will populate this as we find them
188
- const linkedTables = [];
189
- for (let [column, schema] of Object.entries(table.schema)) {
190
- if (schema.type !== FieldTypes.LINK) {
191
- continue;
192
- }
193
- for (let row of enriched) {
194
- if (!row[column] || !row[column].length) {
176
+ const linkedTables = [table];
177
+ for (let row of enriched) {
178
+ // this only fetches the table if its not already in array
179
+ const rowTable = yield getLinkedTable(db, row.tableId, linkedTables);
180
+ for (let [column, schema] of Object.entries(rowTable.schema)) {
181
+ if (schema.type !== FieldTypes.LINK || !Array.isArray(row[column])) {
195
182
  continue;
196
183
  }
197
184
  const newLinks = [];
198
185
  for (let link of row[column]) {
199
186
  const linkTblId = link.tableId || getRelatedTableForField(table, column);
200
- // this only fetches the table if its not already in array
201
187
  const linkedTable = yield getLinkedTable(db, linkTblId, linkedTables);
202
188
  const obj = { _id: link._id };
203
189
  if (link[linkedTable.primaryDisplay]) {
package/dist/db/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const newid = require("./newid");
3
- const { DocumentTypes: CoreDocTypes, getRoleParams, generateRoleID, APP_DEV_PREFIX, APP_PREFIX, SEPARATOR, StaticDatabases, } = require("@budibase/auth/db");
3
+ const { DocumentTypes: CoreDocTypes, getRoleParams, generateRoleID, APP_DEV_PREFIX, APP_PREFIX, SEPARATOR, StaticDatabases, isDevAppID, isProdAppID, } = require("@budibase/auth/db");
4
4
  const UNICODE_MAX = "\ufff0";
5
5
  const AppStatus = {
6
6
  DEV: "development",
@@ -26,6 +26,7 @@ const DocumentTypes = {
26
26
  DATASOURCE_PLUS: "datasource_plus",
27
27
  QUERY: "query",
28
28
  DEPLOYMENTS: "deployments",
29
+ METADATA: "metadata",
29
30
  };
30
31
  const ViewNames = {
31
32
  LINK: "by_link",
@@ -47,6 +48,8 @@ const BudibaseInternalDB = {
47
48
  };
48
49
  exports.APP_PREFIX = APP_PREFIX;
49
50
  exports.APP_DEV_PREFIX = APP_DEV_PREFIX;
51
+ exports.isDevAppID = isDevAppID;
52
+ exports.isProdAppID = isProdAppID;
50
53
  exports.USER_METDATA_PREFIX = `${DocumentTypes.ROW}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`;
51
54
  exports.LINK_USER_METADATA_PREFIX = `${DocumentTypes.LINK}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`;
52
55
  exports.ViewNames = ViewNames;
@@ -266,6 +269,16 @@ exports.getQueryParams = (datasourceId = null, otherProps = {}) => {
266
269
  }
267
270
  return getDocParams(DocumentTypes.QUERY, `${datasourceId}${SEPARATOR}`, otherProps);
268
271
  };
272
+ exports.generateMetadataID = (type, entityId) => {
273
+ return `${DocumentTypes.METADATA}${SEPARATOR}${type}${SEPARATOR}${entityId}`;
274
+ };
275
+ exports.getMetadataParams = (type, entityId = null, otherProps = {}) => {
276
+ let docId = `${type}${SEPARATOR}`;
277
+ if (entityId != null) {
278
+ docId += entityId;
279
+ }
280
+ return getDocParams(DocumentTypes.METADATA, docId, otherProps);
281
+ };
269
282
  /**
270
283
  * This can be used with the db.allDocs to get a list of IDs
271
284
  */
@@ -20,7 +20,7 @@ module.exports = {
20
20
  COUCH_DB_URL: process.env.COUCH_DB_URL,
21
21
  MINIO_URL: process.env.MINIO_URL,
22
22
  WORKER_URL: process.env.WORKER_URL,
23
- SELF_HOSTED: process.env.SELF_HOSTED,
23
+ SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED),
24
24
  AWS_REGION: process.env.AWS_REGION,
25
25
  ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,
26
26
  MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
@@ -49,6 +49,7 @@ module.exports = {
49
49
  BUDIBASE_API_KEY: process.env.BUDIBASE_API_KEY,
50
50
  USERID_API_KEY: process.env.USERID_API_KEY,
51
51
  DEPLOYMENT_CREDENTIALS_URL: process.env.DEPLOYMENT_CREDENTIALS_URL,
52
+ ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS,
52
53
  _set(key, value) {
53
54
  process.env[key] = value;
54
55
  module.exports[key] = value;
@@ -118,14 +118,14 @@ var MySQLModule;
118
118
  }
119
119
  this.client = mysql.createConnection(config);
120
120
  }
121
- buildSchema(datasourceId) {
121
+ buildSchema(datasourceId, entities) {
122
122
  return __awaiter(this, void 0, void 0, function* () {
123
123
  const tables = {};
124
124
  const database = this.config.database;
125
125
  this.client.connect();
126
126
  // get the tables first
127
127
  const tablesResp = yield internalQuery(this.client, { sql: "SHOW TABLES;" }, false);
128
- const tableNames = tablesResp.map((obj) => obj[`Tables_in_${database}`]);
128
+ const tableNames = tablesResp.map((obj) => obj[`Tables_in_${database.toLowerCase()}`]);
129
129
  for (let tableName of tableNames) {
130
130
  const primaryKeys = [];
131
131
  const schema = {};
@@ -160,6 +160,18 @@ var MySQLModule;
160
160
  schema,
161
161
  };
162
162
  }
163
+ // add the existing relationships from the entities if they exist, to prevent them from being overridden
164
+ if (entities && entities[tableName]) {
165
+ const existingTableSchema = entities[tableName].schema;
166
+ for (let key in existingTableSchema) {
167
+ if (!existingTableSchema.hasOwnProperty(key)) {
168
+ continue;
169
+ }
170
+ if (existingTableSchema[key].type === "link") {
171
+ tables[tableName].schema[key] = existingTableSchema[key];
172
+ }
173
+ }
174
+ }
163
175
  }
164
176
  this.client.end();
165
177
  this.tables = tables;