@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
@@ -0,0 +1,46 @@
1
+ const { MetadataTypes } = require("../../constants")
2
+ const CouchDB = require("../../db")
3
+ const { generateMetadataID } = require("../../db/utils")
4
+ const { saveEntityMetadata, deleteEntityMetadata } = require("../../utilities")
5
+
6
+ exports.getTypes = async ctx => {
7
+ ctx.body = {
8
+ types: MetadataTypes,
9
+ }
10
+ }
11
+
12
+ exports.saveMetadata = async ctx => {
13
+ const { type, entityId } = ctx.params
14
+ if (type === MetadataTypes.AUTOMATION_TEST_HISTORY) {
15
+ ctx.throw(400, "Cannot save automation history type")
16
+ }
17
+ ctx.body = await saveEntityMetadata(
18
+ ctx.appId,
19
+ type,
20
+ entityId,
21
+ ctx.request.body
22
+ )
23
+ }
24
+
25
+ exports.deleteMetadata = async ctx => {
26
+ const { type, entityId } = ctx.params
27
+ await deleteEntityMetadata(ctx.appId, type, entityId)
28
+ ctx.body = {
29
+ message: "Metadata deleted successfully",
30
+ }
31
+ }
32
+
33
+ exports.getMetadata = async ctx => {
34
+ const { type, entityId } = ctx.params
35
+ const db = new CouchDB(ctx.appId)
36
+ const id = generateMetadataID(type, entityId)
37
+ try {
38
+ ctx.body = await db.get(id)
39
+ } catch (err) {
40
+ if (err.status === 404) {
41
+ ctx.body = {}
42
+ } else {
43
+ ctx.throw(err.status, err)
44
+ }
45
+ }
46
+ }
@@ -160,8 +160,6 @@ exports.execute = async function (ctx) {
160
160
  )
161
161
 
162
162
  const integration = new Integration(datasource.config)
163
- console.log(query)
164
- // ctx.body = {}
165
163
  // call the relevant CRUD method on the integration class
166
164
  ctx.body = formatResponse(await integration[query.queryVerb](enrichedQuery))
167
165
  // cleanup
@@ -276,7 +276,7 @@ module External {
276
276
  }
277
277
 
278
278
  outputProcessing(
279
- rows: Row[],
279
+ rows: Row[] = [],
280
280
  table: Table,
281
281
  relationships: RelationshipsJson[]
282
282
  ) {
@@ -113,6 +113,7 @@ exports.destroy = async function (ctx) {
113
113
  exports.search = async ctx => {
114
114
  const tableId = getTableId(ctx)
115
115
  try {
116
+ ctx.status = 200
116
117
  ctx.body = await pickApi(tableId).search(ctx)
117
118
  } catch (err) {
118
119
  ctx.throw(400, err)
@@ -23,6 +23,19 @@ const CALCULATION_TYPES = {
23
23
  STATS: "stats",
24
24
  }
25
25
 
26
+ async function storeResponse(ctx, db, row, oldTable, table) {
27
+ row.type = "row"
28
+ const response = await db.put(row)
29
+ // don't worry about rev, tables handle rev/lastID updates
30
+ if (!isEqual(oldTable, table)) {
31
+ await db.put(table)
32
+ }
33
+ row._rev = response.rev
34
+ // process the row before return, to include relationships
35
+ row = await outputProcessing(ctx, table, row, { squash: false })
36
+ return { row, table }
37
+ }
38
+
26
39
  exports.patch = async ctx => {
27
40
  const appId = ctx.appId
28
41
  const db = new CouchDB(appId)
@@ -77,14 +90,7 @@ exports.patch = async ctx => {
77
90
  return { row: ctx.body, table }
78
91
  }
79
92
 
80
- const response = await db.put(row)
81
- // don't worry about rev, tables handle rev/lastID updates
82
- if (!isEqual(dbTable, table)) {
83
- await db.put(table)
84
- }
85
- row._rev = response.rev
86
- row.type = "row"
87
- return { row, table }
93
+ return storeResponse(ctx, db, row, dbTable, table)
88
94
  }
89
95
 
90
96
  exports.save = async function (ctx) {
@@ -118,14 +124,7 @@ exports.save = async function (ctx) {
118
124
  table,
119
125
  })
120
126
 
121
- row.type = "row"
122
- const response = await db.put(row)
123
- // don't worry about rev, tables handle rev/lastID updates
124
- if (!isEqual(dbTable, table)) {
125
- await db.put(table)
126
- }
127
- row._rev = response.rev
128
- return { row, table }
127
+ return storeResponse(ctx, db, row, dbTable, table)
129
128
  }
130
129
 
131
130
  exports.fetchView = async ctx => {
@@ -221,34 +220,47 @@ exports.destroy = async function (ctx) {
221
220
  const appId = ctx.appId
222
221
  const db = new CouchDB(appId)
223
222
  const { _id, _rev } = ctx.request.body
224
- const row = await db.get(_id)
223
+ let row = await db.get(_id)
225
224
 
226
225
  if (row.tableId !== ctx.params.tableId) {
227
226
  throw "Supplied tableId doesn't match the row's tableId"
228
227
  }
228
+ const table = await db.get(row.tableId)
229
+ // update the row to include full relationships before deleting them
230
+ row = await outputProcessing(ctx, table, row, { squash: false })
231
+ // now remove the relationships
229
232
  await linkRows.updateLinks({
230
233
  appId,
231
234
  eventType: linkRows.EventType.ROW_DELETE,
232
235
  row,
233
236
  tableId: row.tableId,
234
237
  })
238
+
239
+ let response
235
240
  if (ctx.params.tableId === InternalTables.USER_METADATA) {
236
241
  ctx.params = {
237
242
  id: _id,
238
243
  }
239
244
  await userController.destroyMetadata(ctx)
240
- return { response: ctx.body, row }
245
+ response = ctx.body
241
246
  } else {
242
- const response = await db.remove(_id, _rev)
243
- return { response, row }
247
+ response = await db.remove(_id, _rev)
244
248
  }
249
+ return { response, row }
245
250
  }
246
251
 
247
252
  exports.bulkDestroy = async ctx => {
248
253
  const appId = ctx.appId
249
- const { rows } = ctx.request.body
250
254
  const db = new CouchDB(appId)
255
+ const tableId = ctx.params.tableId
256
+ const table = await db.get(tableId)
257
+ let { rows } = ctx.request.body
258
+
259
+ // before carrying out any updates, make sure the rows are ready to be returned
260
+ // they need to be the full rows (including previous relationships) for automations
261
+ rows = await outputProcessing(ctx, table, rows, { squash: false })
251
262
 
263
+ // remove the relationships first
252
264
  let updates = rows.map(row =>
253
265
  linkRows.updateLinks({
254
266
  appId,
@@ -257,8 +269,7 @@ exports.bulkDestroy = async ctx => {
257
269
  tableId: row.tableId,
258
270
  })
259
271
  )
260
- // TODO remove special user case in future
261
- if (ctx.params.tableId === InternalTables.USER_METADATA) {
272
+ if (tableId === InternalTables.USER_METADATA) {
262
273
  updates = updates.concat(
263
274
  rows.map(row => {
264
275
  ctx.params = {
@@ -2,11 +2,9 @@ require("svelte/register")
2
2
 
3
3
  const send = require("koa-send")
4
4
  const { resolve, join } = require("../../../utilities/centralPath")
5
- const fetch = require("node-fetch")
6
5
  const uuid = require("uuid")
7
6
  const { ObjectStoreBuckets } = require("../../../constants")
8
7
  const { processString } = require("@budibase/string-templates")
9
- const { budibaseTempDir } = require("../../../utilities/budibaseDir")
10
8
  const { getDeployedApps } = require("../../../utilities/workerRequests")
11
9
  const CouchDB = require("../../../db")
12
10
  const {
@@ -15,7 +13,7 @@ const {
15
13
  TOP_LEVEL_PATH,
16
14
  } = require("../../../utilities/fileSystem")
17
15
  const env = require("../../../environment")
18
- const { objectStoreUrl, clientLibraryPath } = require("../../../utilities")
16
+ const { clientLibraryPath } = require("../../../utilities")
19
17
  const { upload } = require("../../../utilities/fileSystem")
20
18
  const { attachmentsRelativeURL } = require("../../../utilities")
21
19
  const { DocumentTypes } = require("../../../db/utils")
@@ -50,9 +48,6 @@ async function checkForSelfHostedURL(ctx) {
50
48
  }
51
49
  }
52
50
 
53
- // this was the version before we started versioning the component library
54
- const COMP_LIB_BASE_APP_VERSION = "0.2.5"
55
-
56
51
  exports.serveBuilder = async function (ctx) {
57
52
  let builderPath = resolve(TOP_LEVEL_PATH, "builder")
58
53
  await send(ctx, ctx.file, { root: builderPath })
@@ -109,36 +104,3 @@ exports.serveClientLibrary = async function (ctx) {
109
104
  root: join(NODE_MODULES_PATH, "@budibase", "client", "dist"),
110
105
  })
111
106
  }
112
-
113
- exports.serveComponentLibrary = async function (ctx) {
114
- const appId = ctx.query.appId || ctx.appId
115
-
116
- if (env.isDev() || env.isTest()) {
117
- const componentLibraryPath = join(
118
- budibaseTempDir(),
119
- appId,
120
- "node_modules",
121
- "@budibase",
122
- "standard-components",
123
- "package",
124
- "dist"
125
- )
126
- return send(ctx, "/index.js", { root: componentLibraryPath })
127
- }
128
- const db = new CouchDB(appId)
129
- const appInfo = await db.get(DocumentTypes.APP_METADATA)
130
-
131
- let componentLib = "componentlibrary"
132
- if (appInfo && appInfo.version) {
133
- componentLib += `-${appInfo.version}`
134
- } else {
135
- componentLib += `-${COMP_LIB_BASE_APP_VERSION}`
136
- }
137
- const S3_URL = encodeURI(
138
- join(objectStoreUrl(), componentLib, ctx.query.library, "dist", "index.js")
139
- )
140
- const response = await fetch(S3_URL)
141
- const body = await response.text()
142
- ctx.type = "application/javascript"
143
- ctx.body = body
144
- }
@@ -7,7 +7,10 @@
7
7
 
8
8
  <svelte:head>
9
9
  <meta charset="utf8" />
10
- <meta name="viewport" content="width=device-width" />
10
+ <meta
11
+ name="viewport"
12
+ content="width=device-width, initial-scale=1.0, viewport-fit=cover"
13
+ />
11
14
 
12
15
  <title>{title}</title>
13
16
  <link rel="icon" type="image/png" href={favicon} />
@@ -33,6 +33,7 @@ exports.fetchMetadata = async function (ctx) {
33
33
  users.push({
34
34
  ...user,
35
35
  ...info,
36
+ tableId: InternalTables.USER_METADATA,
36
37
  // make sure the ID is always a local ID, not a global one
37
38
  _id: generateUserMetadataID(user._id),
38
39
  })
@@ -9,6 +9,10 @@ const {
9
9
  } = require("@budibase/auth/permissions")
10
10
  const Joi = require("joi")
11
11
  const { bodyResource, paramResource } = require("../../middleware/resourceId")
12
+ const {
13
+ middleware: appInfoMiddleware,
14
+ AppType,
15
+ } = require("../../middleware/appInfo")
12
16
 
13
17
  const router = Router()
14
18
 
@@ -22,7 +26,6 @@ function generateStepSchema(allowStepTypes) {
22
26
  tagline: Joi.string().required(),
23
27
  icon: Joi.string().required(),
24
28
  params: Joi.object(),
25
- // TODO: validate args a bit more deeply
26
29
  args: Joi.object(),
27
30
  type: Joi.string().required().valid(...allowStepTypes),
28
31
  }).unknown(true)
@@ -31,7 +34,6 @@ function generateStepSchema(allowStepTypes) {
31
34
  function generateValidator(existing = false) {
32
35
  // prettier-ignore
33
36
  return joiValidator.body(Joi.object({
34
- live: Joi.bool(),
35
37
  _id: existing ? Joi.string().required() : Joi.string(),
36
38
  _rev: existing ? Joi.string().required() : Joi.string(),
37
39
  name: Joi.string().required(),
@@ -54,11 +56,6 @@ router
54
56
  authorized(BUILDER),
55
57
  controller.getActionList
56
58
  )
57
- .get(
58
- "/api/automations/logic/list",
59
- authorized(BUILDER),
60
- controller.getLogicList
61
- )
62
59
  .get(
63
60
  "/api/automations/definitions/list",
64
61
  authorized(BUILDER),
@@ -84,17 +81,25 @@ router
84
81
  generateValidator(false),
85
82
  controller.create
86
83
  )
84
+ .delete(
85
+ "/api/automations/:id/:rev",
86
+ paramResource("id"),
87
+ authorized(BUILDER),
88
+ controller.destroy
89
+ )
87
90
  .post(
88
91
  "/api/automations/:id/trigger",
92
+ appInfoMiddleware({ appType: AppType.PROD }),
89
93
  paramResource("id"),
90
94
  authorized(PermissionTypes.AUTOMATION, PermissionLevels.EXECUTE),
91
95
  controller.trigger
92
96
  )
93
- .delete(
94
- "/api/automations/:id/:rev",
97
+ .post(
98
+ "/api/automations/:id/test",
99
+ appInfoMiddleware({ appType: AppType.DEV }),
95
100
  paramResource("id"),
96
- authorized(BUILDER),
97
- controller.destroy
101
+ authorized(PermissionTypes.AUTOMATION, PermissionLevels.EXECUTE),
102
+ controller.test
98
103
  )
99
104
 
100
105
  module.exports = router
@@ -22,6 +22,7 @@ const datasourceRoutes = require("./datasource")
22
22
  const queryRoutes = require("./query")
23
23
  const hostingRoutes = require("./hosting")
24
24
  const backupRoutes = require("./backup")
25
+ const metadataRoutes = require("./metadata")
25
26
  const devRoutes = require("./dev")
26
27
 
27
28
  exports.mainRoutes = [
@@ -46,6 +47,7 @@ exports.mainRoutes = [
46
47
  queryRoutes,
47
48
  hostingRoutes,
48
49
  backupRoutes,
50
+ metadataRoutes,
49
51
  devRoutes,
50
52
  // these need to be handled last as they still use /api/:tableId
51
53
  // this could be breaking as koa may recognise other routes as this
@@ -0,0 +1,38 @@
1
+ const Router = require("@koa/router")
2
+ const controller = require("../controllers/metadata")
3
+ const {
4
+ middleware: appInfoMiddleware,
5
+ AppType,
6
+ } = require("../../middleware/appInfo")
7
+ const authorized = require("../../middleware/authorized")
8
+ const { BUILDER } = require("@budibase/auth/permissions")
9
+
10
+ const router = Router()
11
+
12
+ router
13
+ .post(
14
+ "/api/metadata/:type/:entityId",
15
+ authorized(BUILDER),
16
+ appInfoMiddleware({ appType: AppType.DEV }),
17
+ controller.saveMetadata
18
+ )
19
+ .delete(
20
+ "/api/metadata/:type/:entityId",
21
+ authorized(BUILDER),
22
+ appInfoMiddleware({ appType: AppType.DEV }),
23
+ controller.deleteMetadata
24
+ )
25
+ .get(
26
+ "/api/metadata/type",
27
+ authorized(BUILDER),
28
+ appInfoMiddleware({ appType: AppType.DEV }),
29
+ controller.getTypes
30
+ )
31
+ .get(
32
+ "/api/metadata/:type/:entityId",
33
+ authorized(BUILDER),
34
+ appInfoMiddleware({ appType: AppType.DEV }),
35
+ controller.getMetadata
36
+ )
37
+
38
+ module.exports = router
@@ -44,7 +44,6 @@ router
44
44
  authorized(PermissionTypes.TABLE, PermissionLevels.WRITE),
45
45
  controller.uploadFile
46
46
  )
47
- .get("/componentlibrary", controller.serveComponentLibrary)
48
47
  // TODO: this likely needs to be secured in some way
49
48
  .get("/:appId/:path*", controller.serveApp)
50
49
 
@@ -2,6 +2,7 @@ const {
2
2
  checkBuilderEndpoint,
3
3
  getAllTableRows,
4
4
  clearAllAutomations,
5
+ testAutomation,
5
6
  } = require("./utilities/TestFunctions")
6
7
  const setup = require("./utilities")
7
8
  const { basicAutomation } = setup.structures
@@ -10,7 +11,6 @@ const MAX_RETRIES = 4
10
11
 
11
12
  let ACTION_DEFINITIONS = {}
12
13
  let TRIGGER_DEFINITIONS = {}
13
- let LOGIC_DEFINITIONS = {}
14
14
 
15
15
  describe("/automations", () => {
16
16
  let request = setup.getRequest()
@@ -23,15 +23,6 @@ describe("/automations", () => {
23
23
  await config.init()
24
24
  })
25
25
 
26
- const triggerWorkflow = async automation => {
27
- return await request
28
- .post(`/api/automations/${automation._id}/trigger`)
29
- .send({ name: "Test", description: "TEST" })
30
- .set(config.defaultHeaders())
31
- .expect('Content-Type', /json/)
32
- .expect(200)
33
- }
34
-
35
26
  describe("get definitions", () => {
36
27
  it("returns a list of definitions for actions", async () => {
37
28
  const res = await request
@@ -44,7 +35,7 @@ describe("/automations", () => {
44
35
  ACTION_DEFINITIONS = res.body
45
36
  })
46
37
 
47
- it("returns a list of definitions for triggers", async () => {
38
+ it("returns a list of definitions for triggerInfo", async () => {
48
39
  const res = await request
49
40
  .get(`/api/automations/trigger/list`)
50
41
  .set(config.defaultHeaders())
@@ -55,17 +46,6 @@ describe("/automations", () => {
55
46
  TRIGGER_DEFINITIONS = res.body
56
47
  })
57
48
 
58
- it("returns a list of definitions for actions", async () => {
59
- const res = await request
60
- .get(`/api/automations/logic/list`)
61
- .set(config.defaultHeaders())
62
- .expect('Content-Type', /json/)
63
- .expect(200)
64
-
65
- expect(Object.keys(res.body).length).not.toEqual(0)
66
- LOGIC_DEFINITIONS = res.body
67
- })
68
-
69
49
  it("returns all of the definitions in one", async () => {
70
50
  const res = await request
71
51
  .get(`/api/automations/definitions/list`)
@@ -75,7 +55,6 @@ describe("/automations", () => {
75
55
 
76
56
  expect(Object.keys(res.body.action).length).toBeGreaterThanOrEqual(Object.keys(ACTION_DEFINITIONS).length)
77
57
  expect(Object.keys(res.body.trigger).length).toEqual(Object.keys(TRIGGER_DEFINITIONS).length)
78
- expect(Object.keys(res.body.logic).length).toEqual(Object.keys(LOGIC_DEFINITIONS).length)
79
58
  })
80
59
  })
81
60
 
@@ -168,14 +147,13 @@ describe("/automations", () => {
168
147
  automation.definition.steps[0].inputs.row.tableId = table._id
169
148
  automation = await config.createAutomation(automation)
170
149
  await setup.delay(500)
171
- const res = await triggerWorkflow(automation)
150
+ const res = await testAutomation(config, automation)
172
151
  // this looks a bit mad but we don't actually have a way to wait for a response from the automation to
173
152
  // know that it has finished all of its actions - this is currently the best way
174
153
  // also when this runs in CI it is very temper-mental so for now trying to make run stable by repeating until it works
175
154
  // TODO: update when workflow logs are a thing
176
155
  for (let tries = 0; tries < MAX_RETRIES; tries++) {
177
- expect(res.body.message).toEqual(`Automation ${automation._id} has been triggered.`)
178
- expect(res.body.automation.name).toEqual(automation.name)
156
+ expect(res.body).toBeDefined()
179
157
  await setup.delay(500)
180
158
  let elements = await getAllTableRows(config)
181
159
  // don't test it unless there are values to test
@@ -0,0 +1,65 @@
1
+ const { testAutomation } = require("./utilities/TestFunctions")
2
+ const setup = require("./utilities")
3
+ const { MetadataTypes } = require("../../../constants")
4
+
5
+ describe("/metadata", () => {
6
+ let request = setup.getRequest()
7
+ let config = setup.getConfig()
8
+ let automation
9
+
10
+ afterAll(setup.afterAll)
11
+
12
+ beforeEach(async () => {
13
+ await config.init()
14
+ automation = await config.createAutomation()
15
+ })
16
+
17
+ async function createMetadata(data, type = MetadataTypes.AUTOMATION_TEST_INPUT) {
18
+ const res = await request
19
+ .post(`/api/metadata/${type}/${automation._id}`)
20
+ .send(data)
21
+ .set(config.defaultHeaders())
22
+ .expect("Content-Type", /json/)
23
+ .expect(200)
24
+ expect(res.body._rev).toBeDefined()
25
+ }
26
+
27
+ async function getMetadata(type) {
28
+ const res = await request
29
+ .get(`/api/metadata/${type}/${automation._id}`)
30
+ .set(config.defaultHeaders())
31
+ .expect("Content-Type", /json/)
32
+ .expect(200)
33
+ return res.body
34
+ }
35
+
36
+ describe("save", () => {
37
+ it("should be able to save some metadata", async () => {
38
+ await createMetadata({ test: "a" })
39
+ const testInput = await getMetadata(MetadataTypes.AUTOMATION_TEST_INPUT)
40
+ expect(testInput.test).toBe("a")
41
+ })
42
+
43
+ it("should save history metadata on automation run", async () => {
44
+ // this should have created some history
45
+ await testAutomation(config, automation)
46
+ const metadata = await getMetadata(MetadataTypes.AUTOMATION_TEST_HISTORY)
47
+ expect(metadata).toBeDefined()
48
+ expect(metadata.history.length).toBe(1)
49
+ expect(typeof metadata.history[0].occurredAt).toBe("number")
50
+ })
51
+ })
52
+
53
+ describe("destroy", () => {
54
+ it("should be able to delete some test inputs", async () => {
55
+ const res = await request
56
+ .delete(`/api/metadata/${MetadataTypes.AUTOMATION_TEST_INPUT}/${automation._id}`)
57
+ .set(config.defaultHeaders())
58
+ .expect("Content-Type", /json/)
59
+ .expect(200)
60
+ expect(res.body.message).toBeDefined()
61
+ const metadata = await getMetadata(MetadataTypes.AUTOMATION_TEST_INPUT)
62
+ expect(metadata.test).toBeUndefined()
63
+ })
64
+ })
65
+ })
@@ -101,3 +101,17 @@ exports.checkPermissionsEndpoint = async ({
101
101
  exports.getDB = config => {
102
102
  return new CouchDB(config.getAppId())
103
103
  }
104
+
105
+ exports.testAutomation = async (config, automation) => {
106
+ return await config.request
107
+ .post(`/api/automations/${automation._id}/test`)
108
+ .send({
109
+ row: {
110
+ name: "Test",
111
+ description: "TEST",
112
+ },
113
+ })
114
+ .set(config.defaultHeaders())
115
+ .expect("Content-Type", /json/)
116
+ .expect(200)
117
+ }
package/src/app.ts CHANGED
@@ -88,8 +88,8 @@ module.exports = server.listen(env.PORT || 0, async () => {
88
88
  env._set("PORT", server.address().port)
89
89
  eventEmitter.emitPort(env.PORT)
90
90
  fileSystem.init()
91
- await automations.init()
92
91
  await redis.init()
92
+ await automations.init()
93
93
  })
94
94
 
95
95
  process.on("uncaughtException", err => {